R6043 号错误解决方案,包含使用8.0版链接器链接的ASM程序访问C运行库时出现的错误,ASM32中访问C库函数

来源:互联网 发布:python iterator 编辑:程序博客网 时间:2024/05/07 10:37

日前,(本文针对初学朋友)在使用ASM32访问8.0版C运行库时,出现了一些问题,解决过程中也发现网络上很多朋友也碰上了这个问题,这里我把解决方法写出来,希望对碰上类似问题的朋友有点启发,这是一个简略的版本。包含如何在使用8.0版后的编译器链接器编译链接ASM32的程序中调用C库函数的问题,比如printf等。对其两次出现R6043错误的解决办法。

一,先来写程序,写一个简单的MASM32控制台应用程序,并从中访问C库函数,我相信有很多朋友想这么做,因为这样可以不用那么麻烦的亲自调用标准IO接口来进行IO操作,我们这里简单的调用printf函数做演示。在以前,人们都这样做:在ASM程序声明printf的原型,然后就进行调用,用8.0版本之前的Win32程序链接器,链接时加上msvcrt.lib(VC6.0等版本以前带的运行库导入库),如此链接出来,可以运行了,写这文章之前,做过。但是在这里,我们用的是v8.0版本的链接器,库也是8.0版的,也就是Visual studio 2005中带的链接器link.exe v8.0,同时也使用V8.0 的ml.exe。微软新的软件发布策略,也就是伴随NET出现的发布方案中打算使程序集实现自描述,在NET程序中,这已经完全肯定了。同时它也对非NET应用程序寄与此希望,链接时,使用清单来描述程序依赖项,和NET应用程序一样在生成一般默认名为appname.exe.manifest的清单文件(更多信息参见MSDN2005中的内容),这是非常有好处的。于是乎,碰上问题的人不少。

源代码:

;=====================================================================
;
; 调用C库函数
; File:asmcrt.asm
; By: -木月
; Date:-5.28
; Description:演示Win32汇编中调用C库函数.(1)编译工具VS2005自带的32位汇编
; 编译器ML.exe,编译命令行: ml /c /coff /Cp asmcrt.asm (2)链接器是VS2005
; 带的LINK.exe,链接文件为刚编译出的asmcrt.obj和kernel32.lib msvcrt.lib
; 后面两个LIB库从VS2005目录里搜出复制过来和asmcrt.obj存放同一目录。
; 链接命令行:link /SUBSYSTEM:CONSOLE /MANIFEST asmcrt.obj kernel32.lib msvcrt.lib
; (3)链接后钳入程序清单,用VS2005带的工具MT.exe
; 命令行为:mt -manifest asmcrt.exe.manifest -outputresource:asmcrt.exe;1
; 此时程序可以启动了,如果提示缺少库,就到VS2005下搜到相应库,复制到本
; 程序目录。
;---------------------------------------------------------------------

.586
.model flat,stdcall
 option casemap:none

;---------------------------------------------------------------------
;
;
printf  proto c,:DWORD ;声明C库函数printf的原型
ExitProcess proto stdcall,:DWORD ;声明Win32API ExitProcess原型
mainCRTStartup proto c  ;C运行库初始化函数原型,此处必须

;---------------------------------------------------------------------
;
;
.data
message  db '当你看到这行时说明程序已经成功调用C库函数printf',0

;---------------------------------------------------------------------
;
;
.code
_start:     ;代码开始
 call mainCRTStartup  ;@因为程序开始于_start,同时我们
main proc c   ;在后面调用了运行库中的函数,所
 pushad    ;以此处手动初始化运行库,否则错
 lea edx,message  ;@mainCRTStartup自动调用我们的
 push edx   ;main函数,相当于c中的main,必须。
 call printf   ;@调用printf,其位于运行时库中
 adc esp,4
 popad
 xor eax,eax
 invoke ExitProcess,0  ;退出进程
main endp
end _start    ;代码结束

针对本文的程序,编译链接步骤:

1,使用VS2005带的ml.exe编译,命令行为:ml /c /Cp /coff asmcrt.asm 得到 asmcrt.obj 。

2,用VS2005带的link.exe链接,命令行:link /SUBSYSTEM:CONSOLE /MANIFEST asmcrt.obj kernel32.lib msvcrt.lib 链接得到asmcrt.exe和asmcrt.exe.manifest文件。

3,用VS2005中带的mt.exe工具将清单作为资源入应用程序里,方便移动,命令行:mt -manifest asmcrt.exe.manifest -outputresource:asmcrt.exe;1 到此完成操作。

(以上的用到的kernel32.lib msvcrt.lib皆可在vs2005目录中搜到)


 
二,测试:
1),试着在生成程序时不生成清单看程序能否可运行,不生成清单将出现错误R6043,此处针对没有生成清单导致错误发生的问题。 2),在ASM程序中不调用mainCRTStartup函数同样会出现这个问题,因为程序中使用了C运行时库,而库却在用前得不到正确初始化。所以我们须得在程序开始时调用运行库的初始化函数。同时我们的程序也做出相应的main函数,由C运行时库调用它,这形式上和C语言没区别,只是这里我们亲手调用mainCRTStartup罢了

 

附图:

工具:

写本文时有点着急,多处啰嗦,将就着看。完。