【问题标题】:Nasm dotted labelsNasm 虚线标签
【发布时间】:2017-02-26 22:12:01
【问题描述】:

我熟悉 TASM,但不太熟悉 NASM。我读过 NASM 允许使用本地标签,这些标签在名称前用一个点表示。比如代码

.loop: ;some code
       jmp .loop

定义一个名为.loop的局部标号,后面的jmp指令使用引用的地址。
但是,在线阅读一些代码示例,我发现像

这样的行
.label1:
        push label1
        ;other push

我很困惑,因为 label1 没有在任何地方定义(所以它必须以某种方式与 .label1 相关),但我既不理解这种推送的含义,也不理解代码是否应该是 push .label1 。 push label1 是做什么的?

【问题讨论】:

  • 那是损坏的代码并且不起作用。你试过了吗? nasm 抱怨:error: symbol label1 undefined. push .label1 会起作用,并且会推送该标签的地址,这并不奇怪。
  • 我已经下载了源代码和组装+链接的代码,.exe 似乎工作正常,但实际上我没有自己组装代码,因为我没有 nasm。我只是在阅读它以了解与 tasm 的区别。那么你确认 .label1 和 label1 是两个不同的标签吗?
  • 是的,它们是不同的。很容易抓住nasm 它基本上是一个独立的可执行文件。会比在这里问更快;)
  • 其实“.loop:”可以看作是定义符号root_label.loop,而不是.loop。当您在代码符号.loop 中使用时,nasm 将检查哪个是当前根目录,并改为搜索完整的root_label.loop。比如这个工作:global foo.barfoo:.bar:nop,而global .bar会报错,本地标签不能导出。对于简短的测试/实验,您甚至可以在线使用 nasm:tutorialspoint.com/compile_assembly_online.php(当然只能运行 linux 源,但甚至可以编译 DOS/windows 以验证语法)

标签: assembly nasm


【解决方案1】:

前导点是 NASM 用于制作本地标签的语法,它基本上嵌套在最后一个普通(非本地)标签之上。

sum_ints: ; input: ecx is loop counter
    mov eax,0  ; the sum
    jmp .check
    .loopstart:
        add eax,ecx ; add counter to sum
        sub ecx,1 ; decrement counter
        .check:
        cmp ecx,0 ; see if we're done
        jg .loopstart
    ret

这里的“sum_ints”是普通的顶级标签,而.loopstart和.check是本地标签。

.loopstart 变成sum_ints.loopstart,因此您实际上可以从其范围之外引用点标签。 (这让 NASM 将本地标签放入目标文件的符号表中而不会发生冲突。)


NASM 手册中有详细说明: https://www.nasm.us/doc/nasmdoc3.html#section-3.9

本地标签的用处与本地变量在其他语言中的用处相同:它允许您使用简短的合理名称(如“循环”)而不会污染全局命名空间。

【讨论】:

    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2016-05-01
    • 2017-03-02
    • 2018-12-12
    相关资源
    最近更新 更多