Сборка LINUX, x86-64 - Соглашение о вызовах - PullRequest
0 голосов
/ 02 июня 2018

В настоящее время я изучаю основы языка ассемблера для ОС LINUX, процессоров x84-64, компиляторов GCC, и я натолкнулся на пример, который пытается перевести в сборку следующую функцию C:

unsigned long fact(unsigned n)
{
 if (n<=1) 
    return 1;
 else 
    return n*fact(n-1);
}

ThisЭто предложенное решение:

.intel_syntax noprefix
.text
.global fact
.type fact, @function
fact:      PUSH RBP
           MOV RBP, RSP
           CMP EDI, 1
           JBE retour_un
           PUSH RDI
           DEC RDI
           SUB RSP, 8
           CALL fact
           ADD RSP, 8
           POP RDI
           MUL RDI
           JMP retour
retour_un: MOV RAX, 1
retour:    POP RBP
           RET

Однако я не совсем понимаю, как это работает.Из того, что я прочитал, инструкция CALL помещает в стек значение RIP, а затем переходит туда, где его аргумент показывает.В этом случае я понимаю до того момента, когда используется факт CALL.Если эта инструкция реализуется каждый раз, то программа запускается с начала до тех пор, пока RDI == 1, в этом случае она перейдет к retour_un, и все, что находится между ними, никогда не будет выполнено.Может кто-нибудь объяснить мне, где я ошибаюсь и как на самом деле работает этот фрагмент кода сборки?

...