美文网首页
汇编之两个文件的链接

汇编之两个文件的链接

作者: 我在东北玩泥巴_ | 来源:发表于2019-05-19 15:44 被阅读0次

伤不起啊伤不起,恶心了两天了,网上教程几乎也没有,真的是。。。
好了,首先看一下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的时候也是非常智能的

相关文章

  • 汇编之两个文件的链接

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

  • 代码的编译过程

    预处理 编译生成汇编代码 源码->汇编 汇编生成目标文件 链接各种库才能产生最终的正确可执行文件 编译的过程 假如...

  • 编译链接过程gcc以及Makefile

    编译链接过程 预处理 ----> 编译 ----> 汇编 ----> 链接 预处理:任务:处理宏定义,文件包含,条...

  • GDB调试arm汇编程序-入门

    程序生成步骤 写好汇编代码到helloworld.s 编译文件(但是没有链接) 只编译不链接形成.o文件。里面包含...

  • C语言源代码到可执行文件的过程

    源码 vi hello.c 预处理 编译 汇编 链接 头文件和库 执行

  • 10、应用程序的加载流程

    一、编译过程 源文件.h/.m /.cpp -> 预编译 -> 编译 ->汇编 -> 链接(动态库.a/.lib/...

  • C语言程序内存布局

    C语言笔记之02-C语言程序内存布局 我们知道C语言的编译过程分为:预处理-编译-汇编-链接-生成可执行文件,而这...

  • 静态库和动态库

    1. 静态库 在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为...

  • C语言

    第一章 预处理阶段->得到.i文件->编译阶段->得到.s文件->汇编阶段->得到.o文件(二进制文件)->链接阶...

  • [读书笔记]程序员的自我修养--静态链接

    1、编译过程 预处理(预编译 .i)—> 编译(.s) —> 汇编(.o) —> 链接(可执行文件 .a ...

网友评论

      本文标题:汇编之两个文件的链接

      本文链接:https://www.haomeiwen.com/subject/vvlqzqtx.html