信息来源:开放实验室 (openlab.nwpu.edu.cn) 【Visual C++】专栏
复制内容到剪贴板
代码:
#include<windows.h>
int t(int x,int y)
{
_asm
{
mov eax,dword ptr[ebp+8]
add eax,dword ptr[ebp+12]
}
}
int test(int x,int y)
{
_asm
{
pop edi
pop esi
pop ebx
pop ebp
push offset t
ret 0
}
}
int main()
{
printf(" 30+40 = %i\n",test(30,40));
return 0;
}调用test后在test中修改了堆栈返回地址为t的入口地址
test返回后实际上就进入了t()此时堆栈已经是正常调用t
的形态,返回地址为调用test应该正确返回的地址,因此
实际上调用了t并在t中完成了加运算.之后正确返回!
cl /Fa t.c 编译完成,一切正常没有出现错误!
;另由于我英语很烂,能不能说中文,这样可能大家好交流一下.
TITLE t.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
INCLUDELIB LIBC
INCLUDELIB OLDNAMES
PUBLIC _t
; Function compile flags: /Odt
_TEXT SEGMENT
_x$ = 8
_y$ = 12
_t PROC NEAR
; File c:\work\asm-c\t.c
; Line 3
push ebp
mov ebp, esp
; Line 8
mov eax, DWORD PTR [ebp+8]
; Line 9
add eax, DWORD PTR [ebp+12]
; Line 12
pop ebp
ret 0
_t ENDP
_TEXT ENDS
PUBLIC _test
; Function compile flags: /Odt
_TEXT SEGMENT
_x$ = 8
_y$ = 12
_test PROC NEAR
; Line 14
push ebp
mov ebp, esp
push ebx
push esi
push edi
; Line 17
pop edi
; Line 18
pop esi
; Line 19
pop ebx
; Line 20
pop ebp
; Line 22
push OFFSET FLAT:_t
; Line 24
ret 0
; Line 27
pop edi
pop esi
pop ebx
pop ebp
ret 0
_test ENDP
_TEXT ENDS
PUBLIC _main
EXTRN _printf:NEAR
_DATA SEGMENT
$SG52880 DB ' 30+40 = %i', 0aH, 00H
; Function compile flags: /Odt
_DATA ENDS
_TEXT SEGMENT
_main PROC NEAR
; Line 30
push ebp
mov ebp, esp
; Line 31
push 40 ; 00000028H
push 30 ; 0000001eH
call _test
add esp, 8
push eax
push OFFSET FLAT:$SG52880
call _printf
add esp, 8
; Line 32
xor eax, eax
; Line 33
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
.