win32汇编invoke伪指令的问题,究竟是不是编译器的bug?
同样的函数,为什么使用invoke时L2-L1结果是10,而用call时L2-L1得到的结果是5,这个5才是大家认知的结果?程序代码:
.386 .Model Flat, StdCall Option Casemap :None Include windows.inc Include kernel32.inc IncludeLib kernel32.lib Include user32.inc IncludeLib user32.lib .DATA lpFomat db "%lu",0 .DATA? hInstance dd ? AA byte 16 dup (?) BB byte 16 dup (?) .CODE L1: call L2 ;向后面标号CALL时L2-L1=10,向前面标号CALL时L2-L1=5,为什么,怎么解决? L2: pop eax ret START: ;原始写法---------------------------------------------------- push L2-L1 ;这里L2-L1算出的是 5 push offset lpFomat push offset AA call wsprintf add esp,0Ch ;伪指令invoke写法-------------------------------------------- invoke wsprintf,offset BB,offset lpFomat,L2-L1 ;这里L2-L1算出的是 10 invoke MessageBox,0,offset AA,offset BB,0 ;为了直观用信息框显示 invoke ExitProcess,0 END START再贴上反汇编的代码:
程序代码:
00401000 . E8 00000000 call 00401005 00401005 /$ 58 pop eax 00401006 \. C3 retn 00401007 >/$ 68 05000000 push 5 ; /<%lu> = 5 直接L2-L1,结果是5 0040100C |. 68 00304000 push 00403000 ; |Format = "%lu" 00401011 |. 68 08304000 push 00403008 ; |s = test1.00403008 00401016 |. E8 3B000000 call <jmp.&USER32.wsprintfA> ; \wsprintfA 0040101B |. 83C4 0C add esp, 0C 0040101E |. 68 0A000000 push 0A ; /<%lu> = A (10.) 00401023 |. 68 00304000 push 00403000 ; |Format = "%lu" 00401028 |. 68 18304000 push 00403018 ; |s = test1.00403018 0040102D |. E8 24000000 call <jmp.&USER32.wsprintfA> ; \wsprintfA 00401032 |. 83C4 0C add esp, 0C ; invoke这里计算的是10 00401035 |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL 00401037 |. 68 18304000 push 00403018 ; |Title = "" 0040103C |. 68 08304000 push 00403008 ; |Text = "" 00401041 |. 6A 00 push 0 ; |hOwner = NULL 00401043 |. E8 14000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401048 |. 6A 00 push 0 ; /ExitCode = 0 0040104A \. E8 01000000 call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess
[ 本帖最后由 xietao1233 于 2011-9-27 16:59 编辑 ]