@sresort

Почему вычитается 32?

https://godbolt.org/z/E6M3M8jGz
Почему на 4ой строчке идет subq 32ух из rsp
Предположим что max лежит на вершине стэка, т.е rsp
Но почему вычитается 32?
  • Вопрос задан
  • 84 просмотра
Пригласить эксперта
Ответы на вопрос 2
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
почему вычитается 32?

Потому что компилятор использовал стековый кадр для хранения локальных переменных:

pushq   %rbp
movq    %rsp, %rbp
subq    $32, %rsp
movsd   %xmm0, -24(%rbp)
movsd   %xmm1, -32(%rbp)

-- сохранил два аргумента по смещениям -32 и -24

movsd   -32(%rbp), %xmm0
subsd   -24(%rbp), %xmm0
movsd   %xmm0, -8(%rbp)

-- сохранил их разность по смещению -8

movsd   .LC0(%rip), %xmm0
divsd   -8(%rbp), %xmm0
movsd   %xmm0, -16(%rbp)

-- сохранил частное от деления MAX_RAND на разность по смещению -16

4 слота по 8 байт -- 32-байтный стековый кадр.
Ответ написан
@VitalyChaikin
https://en.wikipedia.org/wiki/X86_calling_conventions
int callee(int, int, int);

int caller(void)
{
	return callee(1, 2, 3) + 5;
}
On x86, it might produce the following assembly code (Intel syntax):

caller:
    ; make new call frame
    ; (some compilers may produce an 'enter' instruction instead)
    push    ebp       ; save old call frame
    mov     ebp, esp  ; initialize new call frame
    ; push call arguments, in reverse
    ; (<b>some compilers may subtract the required space from the stack pointer,
    ; then write each argument directly, see below.
    ; The 'enter' instruction can also do something similar)
    ; sub esp, 12      : 'enter' instruction could do this for us</b>
    ; mov [ebp-4], 3   : or mov [esp+8], 3
    ; mov [ebp-8], 2   : or mov [esp+4], 2
    ; mov [ebp-12], 1  : or mov [esp], 1
    push    3
    push    2
    push    1
    call    callee    ; call subroutine 'callee'
    add     esp, 12   ; remove call arguments from frame
    add     eax, 5    ; modify subroutine result
                      ; (eax is the return value of our callee,
                      ; so we don't have to move it into a local variable)
    ; restore old call frame
    ; (some compilers may produce a 'leave' instruction instead)
    mov     esp, ebp  ; most calling conventions dictate ebp be callee-saved,
                      ; i.e. it's preserved after calling the callee.
                      ; it therefore still points to the start of our stack frame.
                      ; we do need to make sure
                      ; callee doesn't modify (or restore) ebp, though,
                      ; so we need to make sure
                      ; it uses a calling convention which does this
    pop     ebp       ; restore old call frame
    ret               ; return
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы