为什么在nasm中使用外部c函数会破坏这段代码?

yur*_*rib 4 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
      int 0x80
Run Code Online (Sandbox Code Playgroud)

而printint的定义如下:

 void printint(int a) { 
   printf("%d\n",a);
 }
Run Code Online (Sandbox Code Playgroud)

我得到的输出是第一次打印(如预期)的3和第二次打印的随机数.有人告诉我的printf()可能会改变CPU寄存器的值没有恢复它们,所以我想保存在堆栈中所有寄存器调用的printf将防止任何寄存器更改前,但显然事实并非如此.
任何人都可以解释为什么奇怪的输出,我该如何解决它?

谢谢.

Fré*_*idi 6

printint()可能正在使用cdecl调用约定.根据该约定,调用者有责任从堆栈中删除推送的参数.

你应该写:

%macro pint 1
    pushad
    push %1
    call printint
    add esp, 4  ; Clean pushed parameter.
    popad
%endmacro
Run Code Online (Sandbox Code Playgroud)