【问题标题】:NASM local label differentiationNASM 本地标签区分
【发布时间】:2015-10-21 06:58:24
【问题描述】:

据我了解,NASM(与所有优秀的汇编程序一样)允许您通过在本地标签前加上句点来定义本地标签,并且它允许以后的定义覆盖以前的定义。

我看到的演示代码如下:

part1  mov   ax, 10
.loop  ; do something
       dec   ax
       jnz   .loop 

part2  mov   ax, 50
.loop  ; do something
       dec   ax
       jnz   .loop 

在这种情况下,后面的定义会覆盖前面的定义,以便选择正确的标签。

但是,我看不出在以下场景中这是如何工作的。

part1  mov   ax, 10
.loop  jz    .fin
       ; do something else
       dec   ax
       jmp   .loop
.fin

part2  mov   ax, 50
.loop  jz    .fin
       ; do something else
       dec   ax
       jmp   .loop
.fin

在第二个循环中的jz .fin 被组装时,.fin早期 实例肯定仍然处于活动状态,它会跳转到错误的位置。

或者 NASM 是否比这更聪明并使用其他方法来决定在任何给定时间哪个标签处于活动状态?

【问题讨论】:

    标签: nasm


    【解决方案1】:

    根据YASM's docs on NASM local labels,本地标签与全局标签相关联。所以我认为如果没有将.fin 的两个实例分开的全局标签,您的示例实际上会发生冲突。

    【讨论】:

      【解决方案2】:

      实际上,这种理解并不完全正确。本地标签不是独立的项目,它们实际上与最近的非本地标签相关联。

      NASM manual section 3.9 Local Labels

      所以第二个代码示例实际上变成了:

      part1       mov   ax, 10
      part1.loop  jz    part1.fin
                  ; do something else
                  dec   ax
                  jmp   part1.loop
      part1.fin
      
      part2       mov   ax, 50
      part2.loop  jz    part2.fin
                  ; do something else
                  dec   ax
                  jmp   part2.loop
      part2.fin
      

      然后问题就消失了。

      事实上,您实际上可以引用本地标签作为非本地标签。换句话说,如果你想离开part1 并完全跳过part2,你可以使用类似的东西:

                  jmp   part2.fin
      

      来自part1 内的某个地方。在part1 中使用.fin 是行不通的,因为这会选择part1.fin,但是完全限定的part2.fin 可以解决问题。

      【讨论】:

        【解决方案3】:

        在第二个循环中 jz .fin 的集合点处,.fin 的早期实例肯定仍然处于活动状态,并且会跳转到错误的位置。

        或者 NASM 是否比这更聪明并使用其他方法来决定在任何给定时间哪个标签处于活动状态?

        让我们找出答案!

        C:\nasm>nasm -f bin -o locals.com locals.asm && ndisasm locals.com
        00000000  B80A00            mov ax,0xa    ; part1:  mov   ax, 10
        00000003  7403              jz 0x8        ; .loop:  jz    .fin
        00000005  48                dec ax        ; dec ax
        00000006  EBFB              jmp short 0x3 ; jmp   .loop
        00000008  B83200            mov ax,0x32   ; .fin: part2:  mov   ax, 50
        0000000B  7403              jz 0x10       ; .loop:  jz    .fin
        0000000D  48                dec ax        ; dec ax
        0000000E  EBFB              jmp short 0xb ; jmp   .loop
                                                  ; .fin:
        

        所以第一个jz .fin 跳转到.fin 的第一个实例,第二个jz .fin 跳转到.fin 的第二个实例。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-26
          • 2015-01-20
          • 2016-12-21
          • 2016-05-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-21
          相关资源
          最近更新 更多