【问题标题】:How subroutine gets executed without being called?子程序如何在不被调用的情况下执行?
【发布时间】:2018-09-01 16:47:03
【问题描述】:

我对汇编 (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 声明而失败?标签不是封装吗?提前感谢您的任何解释!

【问题讨论】:

  • 是的,它失败了,CPU 不会停止并在每一条指令之后继续执行下一条和下一条指令。而标签只是内存中的书签(源代码中特定位置的内存地址),它们没有封装或任何东西,它们对最终的机器代码完全不可见,只有在汇编过程中对汇编程序可见。

标签: assembly nasm subroutine


【解决方案1】:

正如 @ped7g 指出的那样,执行例程的原因是因为它从打印例程中失败了。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 2021-11-25
    • 2021-10-22
    相关资源
    最近更新 更多