Assembler pomoc w zrozumieniu instrukcji

Odpowiedz Nowy wątek
2019-09-01 18:37
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
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
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)


01010100 01110101 01110100 01100001 01101010 00100000 01101110 01101001 01100101 00100000 01101101 01100001 00100000 01101110 01101001 01100011 00100000 01100011 01101001 01100101 01101011 01100001 01110111 01100101 01100111 01101111 00101110 00100000 01001001 01100011 00100000 01110011 01110100 01101111 01101110 01110100 00101110
edytowany 2x, ostatnio: stivens, 2019-09-01 22:57

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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