Assembler pomoc w zrozumieniu instrukcji

Odpowiedz Nowy wątek
2019-09-01 18:37

Rejestracja: 1 rok temu

Ostatnio: 14 godzin temu

0

Mam taki kod:

  mov eax , 1
  mov ebx , 2
  push eax
  push ebx
  call a
  add esp , 8
  jmp koniec
a:
  push ebp //DO TEGO MIESJCA ROZUMIEM
  mov ebp , esp
  mov eax , [ ebp+8]
  add eax , [ ebp+12]
  pop ebp
  ret
koniec:

Nie rozumiem jaką wartość ma EBP w instrukcji PUSH. Mógłby ktoś wyjaśnić czym jest i do czego służy EBP? Naczytałem się już o tym, ale dalej nic nie rozumiem :(

Drugie pytanie to, dlaczego na koniec w EAX znajduje się wartość 120:

mov eax , 5
push eax
dec eax
call silnia (liczy silnie dla argumentu ze stosu i zwraca wynik przez rejestr EBX)
add esp , 4
mov eax , ebx

Mi wychodzi 24:

Umieść 5 w EAX
Dodaj EAX na stos
Zmniejsz EAX o 1 czyli na stosie mamy 4.
Liczymy silnie dla 4 = 24
Zmniejszamy wskaźnik stosu
Umieszczamy EBX (czyli wartość 24) w EAX.

Gdzie robię błąd?

edytowany 1x, ostatnio: anckor, 2019-09-01 18:50

Pozostało 580 znaków

2019-09-01 22:19

Rejestracja: 3 lata temu

Ostatnio: 3 godziny temu

1

Wystarczy zerknąć na przykładowy kod w godbolcie -> https://godbolt.org/ Widać tam, że kompilator pod arch x64 wrzuca normalnie mov rbp, rsp. Tak samo testowałem gcc lokalnie z defaultowymi optymalizacjami i dla takiego kodu:

#include <stdio.h>

int count(int a, int b) {
    return a + b;
}

int main() {
    int result = count(2, 2);
    printf("%d\n", result);
    return 0;
}

Kompilator wypluł dokładnie to:

push   rbp
mov    rbp,rsp
sub    rsp,0x10
mov    esi,0x2
mov    edi,0x2
call   0x64a <count>
mov    DWORD PTR [rbp-0x4],eax
mov    eax,DWORD PTR [rbp-0x4]
mov    esi,eax
lea    rdi,[rip+0xa0]        # 0x724
mov    eax,0x0
call   0x520 <[email protected]>
mov    eax,0x0
leave  
ret

Komenda kompilująca:

gcc test.c -o test

Czyli w większości przypadków po ebp/rbp jest jednak adresacja. Za to jeśli skompilujemy z flagą -fomit-frame-pointer tak jak sugerowałem wcześniej to kompilator rzeczywiście używa bezpośrednio esp/rsp do adresacji:

sub    rsp,0x18
mov    esi,0x2
mov    edi,0x2
call   0x64a <count>
mov    DWORD PTR [rsp+0xc],eax
mov    eax,DWORD PTR [rsp+0xc]
mov    esi,eax
lea    rdi,[rip+0xa3]        # 0x724
mov    eax,0x0
call   0x520 <[email protected]>
mov    eax,0x0
add    rsp,0x18
ret    

Komenda:

gcc test.c -o test -fomit-frame-pointer


edytowany 1x, ostatnio: Shizzer, 2019-09-01 22:24

Pozostało 580 znaków

2019-09-01 22:45

Rejestracja: 4 lata temu

Ostatnio: 2 godziny temu

2

W takim razie mea culpa
nie wiem skad mi sie to wzielo ;) (moze nauczylem sie podswiadomie mapowac rbp na rsp :D w glowie i za mocno weszlo)

edytowany 2x, ostatnio: stivens, 2019-09-01 22:57

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0