子程序如何在不被调用的情况下执行?

时间:2018-09-01 16:47:03

标签: assembly nasm subroutine

我对汇编(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 :(得分:3)

正如 @ ped7g 所指出的那样,执行该例程的原因是因为它脱离了打印例程。

在汇编中,call指令将返回地址保存到内存(在堆栈上),并且弹出它(即返回所述点),直到遇到{{ 1}}语句。除非有某种跳转(调用/退出/ jmp),无论标签如何,执行总是继续到下一条指令。

对于标签,它们只是某些内存位置的“昵称”,使程序员更容易编写汇编代码。无需记住十六进制地址并跳转到该地址,您只需使用标签即可对其进行引用。那是他们唯一的功能;这种连接(在十六进制地址和标签之间)是由汇编程序(和当前文件外部标签的链接器,还是绝对引用而不是相对引用的链接器)完成的。