Почему использование внешней функции C в Nasm нарушает этот код? - PullRequest
3 голосов
/ 25 декабря 2010

Я столкнулся с проблемой при использовании внешней функции 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

пока printint определяется так:

 void printint(int a) { 
   printf("%d\n",a);
 }

вывод, который я получаю, - 3 из первого отпечатка (как и ожидалось) и случайное число из второго отпечатка. Мне сказали, что printf () может изменить значения регистров процессора, не восстанавливая их, поэтому я подумал, что сохранение всех регистров в стеке до вызова printf предотвратит изменение любых регистров, но, очевидно, это не так. Может кто-нибудь объяснить, почему странный вывод и как я могу это исправить?

Спасибо.

1 Ответ

5 голосов
/ 25 декабря 2010

printint(), вероятно, использует соглашение о вызовах cdecl . В соответствии с этим соглашением, вызывающая сторона несет ответственность за удаление переданных параметров из стека.

Вы должны написать:

%macro pint 1
    pushad
    push %1
    call printint
    add esp, 4  ; Clean pushed parameter.
    popad
%endmacro
...