为什么在nasm中使用外部c函数会破坏此代码?
我在使用外部c函数调试nasm程序时遇到了一个问题为什么在nasm中使用外部c函数会破坏此代码?,c,assembly,external,nasm,C,Assembly,External,Nasm,我在使用外部c函数调试nasm程序时遇到了一个问题 %macro pint 1 pushad push %1 call printint popad %endmacro section .text extern printint global main main: mov eax, 3 pint eax dec eax pint eax mov eax,1 mov ebx,0
%macro pint 1
pushad
push %1
call printint
popad
%endmacro
section .text
extern printint
global main
main:
mov eax, 3
pint eax
dec eax
pint eax
mov eax,1
mov ebx,0
int 0x80
printint的定义如下:
void printint(int a) {
printf("%d\n",a);
}
我得到的输出是第一次打印的3(如预期的)和第二次打印的随机数。
我被告知printf()可能会更改cpu寄存器值而不还原它们,因此我认为在调用printf之前保存堆栈上的所有寄存器可以防止任何寄存器更改,但显然不会更改。有人能解释为什么会有奇怪的输出吗?我该如何修复它 谢谢。
printint()
可能正在使用调用约定。根据该约定,调用方负责从堆栈中删除推送的参数
你应该写:
%macro pint 1
pushad
push %1
call printint
add esp, 4 ; Clean pushed parameter.
popad
%endmacro
您似乎正在为Linux编写代码(取决于您终止程序的方式)。在这个系统上,只有EAX、ECX和EDX中的值会被调用阻塞。此外,从
main
返回值比手动调用\u exit
系统调用要好:mov eax,0;ret
。对于printint
函数来说,这可能不是问题,但一般来说,堆栈指针在调用
完成隐式推送后必须始终可以被16整除(因此在printint
中推送参数之前,应该sub eax,8
,然后撤消该操作)。弗里德里克对你实际问题的诊断是正确的。