Как выполняется подпрограмма без вызова? - PullRequest
0 голосов
/ 01 сентября 2018

Я очень новичок в сборке (x86_64) и наткнулся на учебник, который предоставляет простую программу для печати строк с неопределенной длиной. Программа выглядит следующим образом:

section .data
        text db "Hello, World!",10,0

section .text
        global _start

_start:
    mov rax, text
    call _print

    mov rax, 60
    mov rdi, 0
    syscall

_print:
        push rax
        mov rbx, 0

_printLoop:
        inc rax
        inc rbx
        mov cl, [rax]
        cmp cl, 0
        jne _printLoop

        mov rax, 1
        mov rdi, 1
        pop rsi
        mov rdx, rbx
        syscall

        ret

Я понял логику этого, кроме одного: как выполняется подпрограмма _printLoop, когда она вообще не вызывается? Это как ... провалиться, потому что _print не имеет ret заявления? Разве ярлыки не инкапсулируются? Заранее спасибо за любые объяснения!

1 Ответ

0 голосов
/ 01 сентября 2018

Как указывало @ ped7g , причина того, что процедура выполняется, заключается в том, что она проваливается из процедуры печати. ​​

В сборке инструкция call сохраняет адрес возврата в памяти (в стеке), а не выводит его (т.е. возвращает в указанную точку), пока не встретит оператор ret. Выполнение всегда продолжается до следующей инструкции, если не существует какого-либо перехода (call / ret / jmp), независимо от меток.

Что касается меток, они являются просто "псевдонимами" для определенных областей памяти, чтобы программистам было проще писать ассемблерный код. Вместо того, чтобы запоминать шестнадцатеричный адрес и переходить к нему, вы можете просто использовать метку для ссылки на него. Это их единственная функция; это соединение (между шестнадцатеричным адресом и меткой) выполняется ассемблером (и компоновщиком для меток вне текущего файла или для абсолютных, а не относительных ссылок).

...