汇编之两个文件的链接

伤不起啊伤不起,恶心了两天了,网上教程几乎也没有,真的是。。。
好了,首先看一下main.asm的代码:

include \masm32\include\masm32rt.inc
    .data?
      value dd ?
    .data
      item dd 0
    .code
start:
    call main
    inkey
    exit
main proc
    cls
    print "Hello World",13,10
    ret
main endp
end start

平淡无奇的代码,而且是教程代码,没道理出错,.386也没有也不知道它是默认谁的,编译了一下,能行,出来helloworld了
然后写一个sub.asm,然后link进去,代码同上
出现问题了:
sub.obj : error LNK2005: _start already defined in main.obj
sub.obj : error LNK2005: _main@0 already defined in main.obj
main.exe : fatal error LNK1169: one or more multiply defined symbols found
解决方法是:把sub.asm的start去掉,把main改成subproc,重新编译
好,现在仍然能够成功运行出helloworld
然后,给sub.asm里添加上一个public
好,同样可以,然后再在main.asm里添加上extrn
出现错误:
main.obj : error LNK2001: unresolved external symbol _vars
main.exe : fatal error LNK1120: 1 unresolved externals
看了一下,原来是自己变量名写错了。。。改成items
成功了
因为在cmd里,没办法进行mov ah, 2 然后int 21h,恐怕不行
然后再是函数,public一个函数出来
出现问题:
main.obj : error LNK2001: unresolved external symbol _subproc
main.exe : fatal error LNK1120: 1 unresolved externals
问题与上面如出一辙,但有一个问题是,这回名字并没有写错啊?
去掉items,不行
改动.code 为 .code code1
出现问题:
sub.asm(11) : fatal error A1010: unmatched block nesting : subproc
看来不行
把subproc改成near?
仍然不行,出错提示上同
在网上查了一下,发现有用proto,难道extrn不能用了吗?
竟然成功了。。。
但是如何打印在控制台上就有点不会了。。。
好,完全成功
然后是编译成lib的问题
好,首先一个超简单的命令:

D:\masm32\bin\lib sub.asm
sub.asm : fatal error LNK1136: invalid or corrupt file
我并不会使用lib,看看怎么用
网上说,dos下是无法使用lib的
解决方法:用lib sub.obj , 即改成obj文件就好了
D:> link main.obj sub.lib
出现错误:
LINK : fatal error LNK1221: 无法推导出子系统,必须定义它
解决方法:使用如下:
link /sussystem:console main.obj sub.lib
出现错误:
LINK : warning LNK4044: unrecognized option "sussystem:console"; ignored
LINK : fatal error LNK1221: a subsystem can't be inferred and must be defined
解决办法:原来我忘记删东西了
但是现在还是上面的哪个问题,怎么办?
用includelib的方法,在main.sub里加上includelib sub.lib,重新编译
成功
妈蛋

好了,我们来总结一下汇编两个文件如何编译成一个可执行程序

  1. 把sub.asm通过include sub.asm导入进去,实际上就是在include位置把sub.asm的代码完全拷贝,在ml的时候就已经导入进去并生成obj文件,因此不用在link的时候添加sub.obj,但是要注意什么事情呢,就是要像在一个文件里写那样,不能再重复引用一些文件了,不然会报重的,连end也没有,也没有数据段定义,也没有code段定义,就是简单的一段函数,或者一段数据定义,如果出现end,那么很明显的是,由于main函数被放在end下面,它就会提示不存在main定义,就是这样

WARNING Duplicate include file windows.inc

就是这个出错提示

记得区分大小写,高级汇编支持判断大小写的

  1. 通过public和extrn的办法,对于变量,能通过public和extrn,但是对于函数,却只能使用proto(对于masm6而言),用invoke来调用函数,子程序先声明后调用,用proc伪指令,先调用后声明用proto伪指令,proto就是告诉编译器,调用的子程序,定义这条指令的后边,也就是说,proto是声明伪指令,proc为定义伪指令,32位汇编增加了PROTO-INVOKE组合,也兼容PROC-CALL组合,另外,proto的另一个重要功能是指定程序的外部过程,默认情况下,MASM使所有的过程都是public属性,即允许它们能被同一程序中任何其他模块调用,在后面使用限定词private可以覆盖这个属性。。。扯远了,对于两个obj链接而言,sub.asm这时候就像一个更加独立的模块了,它有自己的data,code,外加一个不带标识符的end,使用obj的好处就是它能够同时定义data和code,而且独立性更强,它可以自己include别的文件,但是在link的时候,就需要同时点明两个文件,并且第一个obj文件会生成exe文件。
  2. 通过lib库,之所以把sub.asm编译成lib库,是因为lib库是二进制文件,不仅具有保密性,而且在include的时候也是非常智能的

你可能感兴趣的:(汇编之两个文件的链接)