Что делает этот ассемблерный код и как будет выглядеть код C? - PullRequest
0 голосов
/ 24 сентября 2018

Я пытаюсь разобрать файл, и один из разделов содержал это.Что это делает?Как бы это выглядело в C?

Я считаю, что он копирует 40 в ebp-8 и копирует 20 в ebp-4.Затем он вызывает функцию func :.Он выполняет несколько команд, добавляя edx в eax, а затем вычитает 4 из него.После выхода из функции func: он добавляет 8 к esp.Я на правильном пути?

func:
push ebp
mov ebp, esp
mov edx, DWORD PTR [ebp+8]
mov eax, DWORD PTR [ebp+12]
add eax, edx
sub eax, 4
pop ebp
ret
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
push DWORD PTR [ebp-4]
push DWORD PTR [ebp-8]
call func
add esp, 8
leave
ret

РЕДАКТИРОВАТЬ: Так вы бы согласились, что результат C будет следующим?

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

int func(int d, int e)
{
    int sum = d + e;
    int result = sum - 4;
    return result;
}

int main(void)
{
    int a = 40;
    int b = 20;
    int c = func(a,b);
    printf("Result is: %d\n", c);
}

1 Ответ

0 голосов
/ 24 сентября 2018

Сломанный код выглядит следующим образом:

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.

...