Как подпрограмма выполняется без вызова?

Я очень новичок в сборке (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? Разве метки не являются инкапсуляцией? Заранее спасибо за любое объяснение!


person patateskafa    schedule 01.09.2018    source источник
comment
да, он проваливается, ЦП не останавливается и продолжает выполнять следующую и следующую инструкцию после каждой предыдущей. А метки — это просто закладки в память (адрес памяти конкретной позиции в исходном коде), они ничего не инкапсулируют, они как бы совершенно невидимы для конечного машинного кода, видны ассемблеру только во время сборки.   -  person Ped7g    schedule 01.09.2018


Ответы (1)


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

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

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

person SongBird    schedule 01.09.2018