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 18:49
0

Jezeli sie nie myle to wg. ABI EBP ma callee save policy
Program wykorzystuje ten rejestr wiec najpierw robi backup wrzucajac zawartosc na stos a na koncu przywraca poprzedni stan

Ide jeszcze sie upewnic co do tego save policy


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 18:57

Pozostało 580 znaków

2019-09-01 18:53
1

Screenshot_20190901-185258.png


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
Pokaż pozostałe 3 komentarze
Eax jest zalezne tylko od argumentu - stivens 2019-09-01 19:55
Dla tej procedury zawartosc ebp przestala istniec - stivens 2019-09-01 19:56
Ale tam jest coś takiego jak: mov eax, [ ebp+8] i add eax, [ ebp+12], czyli muszę wiedzieć coś o EBP. - anckor 2019-09-01 19:57
EBP to tak na prawde teraz stack pointer... - stivens 2019-09-01 19:58
mov ebp , esp - stivens 2019-09-01 19:58

Pozostało 580 znaków

2019-09-01 19:00
0

A drugie pytanie (edytowales post)

'call silnia (liczy silnie dla argumentu ze stosu i zwraca wynik przez rejestr EBX)'

Chyba jasne? :D


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 1x, ostatnio: stivens, 2019-09-01 19:00

Pozostało 580 znaków

2019-09-01 19:10
0
stivens napisał(a):

A drugie pytanie (edytowales post)

'call silnia (liczy silnie dla argumentu ze stosu i zwraca wynik przez rejestr EBX)'

Chyba jasne? :D

Czyli gdy robię dec EAX to jedynie w EAX mam 5 - 1 = 4, a na stosie dalej leży wartość 5?

Pozostało 580 znaków

2019-09-01 19:11
1

No tak


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
Ok, myślałem, że dec EAX zmiejszy mi też to co wrzuciłem na stos. - anckor 2019-09-01 19:14
Nie no, jakim prawem ;) wtedy by Ci komputer nie dzialal bo masz tylko kilkanascie rejestrow a nie szlo by ich backupowac - stivens 2019-09-01 19:19
I w ogole stos by nie mial sensu - stivens 2019-09-01 19:21

Pozostało 580 znaków

2019-09-01 20:06
1

Ale tam jest coś takiego jak: mov eax, [ ebp+8] i add eax, [ ebp+12], czyli muszę wiedzieć coś o EBP

Dobrze wiec tak:

push eax
push ebx
To jest 8 bajtow zaalokowanych na stosie

call a
To wrzuca 4 bajty adresu powrotu na stos (i wola procedure)

push ebp
backup ebp, kolejne 4 bajty na stosie

mov ebp , esp
Stack pointer zastepuje zawartosc ebp

mov eax , [ ebp+8]
add eax , [ ebp+12]
Wrzucamy jeden z argumentow do eax (offset 8 bajtow bo adres powrotu i backup ebp) i dodajemy drugi (bazowy offset + 4 bajty = 12)

Czyli 1+2? / ew 2+1, whatever


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 3x, ostatnio: stivens, 2019-09-01 20:30

Pozostało 580 znaków

2019-09-01 20:22
2

Rejestr ebp służy przede wszystkim do "zarządzania" mechanizmem funkcji i ich zmiennych lokalnych. Generalnie funkcja jest swego rodzaju abstrakcją, a ktoś dobrze wymyślił jak przedstawić pojęcie podprogramu wykorzystując do tego pamięć procesu, a konkretnie część tej pamięci jaką jest stos.

Napisałem na swoim blogu krótki artykuł na ten temat z tym, że dla architektury x64 -> https://shizz3r.blogspot.com/[...]ineering-puzzles-1-stack.html W każdym razie @anckor musisz poczytać sobie o calling conventions, czyli o tym jak funkcje i ich wywołanie jest reprezentowane na niskim poziomie abstrakcji. Dodam, że konwencje wywołań są różne dla różnych architektur.

Przy czym ten fragment mov ebp , esp jest jak najbardziej używany przez kompilatory. Oznacza, że możemy adresować zmienne lokalne funkcji opierając się na rejestrze ebp - rejestr ten staje się naszym base pointerem sama nazwa tego rejestru to przecież extended base pointer. Oczywiście można również powiedzieć kompilatorowi, że chcemy odwoływać się do zmiennych używając rejestru esp bezpośrednio, ale jest to dość niebezpieczne i rzadko praktykowane. Odnośnik do poczytania o tym -> https://stackoverflow.com/que[...]cc-option-fomit-frame-pointer

Podsumowując: W zdecydowanej większości przypadków ebp używamy do tego, żeby dostawać się do zmiennych lokalnych funkcji oraz jej argumentów. (w x86, w x64 tylko gdy tych argumentów jest na tyle dużo, że nie mieszczą się w odpowiednich rejestrach)


Pozostało 580 znaków

2019-09-01 20:25
0

Zakladajac ze kompilator nie jest zbugowany (nie robi esp+8 jako modyfikacja rejestru kiedy chce odwolac sie do pamieci) to w jaki sposob odwolanie [ebp+8] jest bezpieczniejsze niz [esp+8]?

Ja przynajmniej na linuxie 64bitowym i gcc widywalem raczej rsp


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 3x, ostatnio: stivens, 2019-09-01 20:34

Pozostało 580 znaków

2019-09-01 20:45
1

Źle się wyraziłem. Unikanie ebp jako frame pointer jest niebezpieczne podczas samodzielnego programowania w Asmie, ponieważ nieraz ciężko jest śledzić stan stosu i możemy niechcący modyfikować nie te bajty co chcieliśmy. Kompilator niekoniecznie ma z tym problem, zależy jaki poziom optymalizacji mu podamy


Pozostało 580 znaków

2019-09-01 20:49
1

Noo ten zestaw ktory podalem wyzej bez zadnej optymalizacji rsp uzywa. Musialbym jeszcze sprawdzic zeby nie sklamac na pewno ale jesli pamiec mnie nie myli no to rsp widuje od kompilatora.

To z tym ze czlowiek to pisal to moze sie nie pomylilem


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
Też później to sprawdzę. Ciekawa sprawa - Shizzer 2019-09-01 20:52

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