;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;C/CPP 程序 demo.cpp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include
#ifdef __cplusplus
extern "C"
{
#endif
extern void _stdcall _nasm(int *val);
extern void _stdcall _masm(int *val);
#ifdef __cplusplus
};
#endif
int main(int argc, char* argv[])
{
int val = 1;
_nasm(&val);
printf("nasm: %d/n",val);
_masm(&val);
printf("masm: %d/n",val);
return 0;
}
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;nasm.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
cpu 386
[section .data]
$var1 db 1
[section .text]
global __nasm@4 ;函数声明,只有声明后函数才是公有的这样在C/CPP中才能访问才可被链接器识别
__nasm@4:
push ebp
mov ebp,esp
mov edi,[esp+8]
mov eax,[$var1]
mov [edi],eax ; 写到edi所指向的地址内(通过[]寻址方式)
leave
ret 4
;=============================================================================
;注:
;若使用stdcall调用约定,则需要手工加上__原函数名@参数长度,否则链接程序无法识别此函数(C调用约定则不需要)
;=============================================================================
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;masm.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
_masm PROTO,PVal:PTR DWORD;函数声明,只有声明后函数才是公有的这样在C/CPP中才能访问,才可被链接器识别
.data
var1 dd 2
.code
_masm PROC PVal:PTR DWORD
; 编译器自动加上:
; push ebp
; mov ebp,esp
; 对于内存变量(全局变量和局部变量),无论是否时确用[],MASM都会隐式加上[内存变量/局部变量]内存寻址方式
; 只有offset 全局变量 / lea 局部变量 才可以返回内存地址
mov edi,[PVal]; 与 mov edi,PVal 结果一样
mov eax,[var1]; 与 mov eax,var1 结果一样
mov [edi],eax ; 写到edi所指向的地址内内(通过[]寻址方式)
ret
; ret 自动变为
; leave
; ret 4
_masm ENDP
end
;=============================================================================
;注:
; MASM 的 Proc 定义
; 起始:编译器自动加上
; push ebp
; mov ebp,esp
; 结束:编译器在ret语句前,自动加上leave,如果调用约定中规定由函数调整堆栈指针,则自动在ret后加上参数的总字节长度
; leave
; ret n
; 使用stdcall调用约定时,编译器隐式将函数名改为 _原函数名@参数长度,所有不需要手工加上(加上反而错)
; 默认情况下MASM的PROC 定义为公有的,可以在PROC 后直接跟上范围限制的标记如PRIVATE
;=============================================================================
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;汇编后代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;demo.cpp
22: _nasm(&val);
0040103F lea eax,[ebp-4]
00401042 push eax
00401043 call __nasm@4 (004010a0)
;nasm.asm
__nasm@4:
004010A0 push ebp
004010A1 mov ebp,esp
004010A3 mov edi,dword ptr [esp+8]
004010A7 mov eax,[___xt_z+104h (00424a30)] ; 全局变量
004010AC mov dword ptr [edi],eax
004010AE leave
004010AF ret 4
--------------------------------------------------------------------------------
;demo.cpp
25: _masm(&val);
00401059 lea edx,[ebp-4]
0040105C push edx
0040105D call @ILT+0(__masm@4) (00401005)
@ILT+0(__masm@4):
00401005 jmp __masm@4 (004010b8)
;masm.asm
__masm@4:
004010B8 push ebp
004010B9 mov ebp,esp
004010BB mov edi,dword ptr [ebp+8]
004010BE mov eax,[___xt_z+108h (00424a34)] ; 全局变量
004010C3 mov dword ptr [edi],eax
004010C5 leave
004010C6 ret 4