Wpis z mikrobloga

#assembler #asembler #x86 #x64 #programowanie #nasm

Mam coś takiego

hello:
  push rbp ; robimy ramkę stosu
  mov rbp, rsp
  sub rsp, 16 ; stack musi być wyrównany do 16 bajtów w SysV ABI, ofc w tym przykładzie w ogóle nie muszę sobie robić tych 16 bajtów, bo ich nie używam, ale wstawiam, żeby napisać ten komentarz o wyrównaniu stosu :P

  mov rcx, 10 ; loop counter
hello_loop:
  mov rdi, hello_fmt
  mov rsi, rcx
  push rcx ; zapisuję rcx, bo _printf bruździ w rejestrach
  push rcx ; a ponieważ stos musi być wyrównany do 16 B to musimy albo zrobić sub rsp, 8 albo dwa razy zrobić push, inaczej dostaniemy segfaulta
  call _printf
  pop rcx ; przywracam rcx
  pop rcx ; wyrównuję stos
  loop hello_loop

  add rsp, 16 ; zwalniamy stos
  pop rbp
  ret

section .data
hello_fmt: db "Hello, %d", 10, 0

No i wszystko ładnie. Tylko dlaczego to wyrównanie nie tyczy się to pierwszego push rbp? Na początku mamy odjęte 8 (push rbp), potem 16 (sub rsp, 16), potem drugie 16 (podwójny push). To gdzie jest brakujące 8?
  • 5
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@cecidimus: hmmm, ja to się tak z doskoku douczam jak mnie najdzie akurat ochota i w sumie bardzo mało umiem. Myślę, że lepiej jak spytasz tego pana – @Gynvael + polecam jego kanał na yt https://www.youtube.com/user/GynvaelColdwind/videos

No ale powiem jak jest u mnie

Na początku to na studiach miałem 16-bitowy asm w MSDOS i potem jeszcze MIPS, takie zupełne podstawy. Jeden projekt z zamianą tekstu, drugi jakiś
  • Odpowiedz
Na początku mamy odjęte 8 (push rbp), potem 16 (sub rsp, 16), potem drugie 16 (podwójny push). To gdzie jest brakujące 8?


@zwei: Te 8 bajtów zostanie zajęte przez "return adress" pod który ma wrócic funkcja po wywołaniu. Jest to zazwyczaj odkładane na stosie przez "call" i zdejmowane przez "ret"
  • Odpowiedz