Сломанный код выглядит следующим образом:
func:
; enter 0, 0
push ebp
mov ebp, esp
; entered func with no local variables
; get first param in edx
mov edx, DWORD PTR [ebp+8]
; get second param in eax
mov eax, DWORD PTR [ebp+12]
add eax, edx ; eax += edx
sub eax, 4 ; eax -= 4
; to avoid segfault, you should first `mov esp, ebp`
; but works here, since ESP was not changed, so getting back ESP's old value is not required
pop ebp
ret
main:
; enter 16, 0
push ebp
mov ebp, esp
sub esp, 16 ; adds 4 elements on the stack
; entered main with 4 local variables on stack
; writing on 2 local variables
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
; push 2 params on the stack and call `func`
push DWORD PTR [ebp-4] ; second param
push DWORD PTR [ebp-8] ; first param
call func ; calls `func(first, second)`, returns EAX = 56
; delete 2 elements off the stack
add esp, 8
; leave entered function (get back ESP from before entering)
leave
; return to caller
ret
Я думаю, что, взяв объяснение в комментариях (отмечено ;
), вам должно быть легко перевести его в код на Cсебя.
РЕДАКТИРОВАТЬ: Как отметил Питер Кордес, Assembly не знает никаких типов данных, таких как int
или long int
.При сборке x86, вы используете общие регистры, а с соглашениями C любое 32-битное значение возвращается в EAX
, в то время как 64-битное значение возвращается в EDX:EAX
, что означает, что содержимое EDX
будет старшими 32 битами.
Но если метка main
является классической функцией int main()
в C и точкой входа в программу, мы можем предположить, что func
выглядит также как int func(int p1, int p2)
в C, я считаю,возвращаемое значение EDX
никогда не используется, а функция int main()
заканчивается на return 56;
с 56 в EAX
.