NASM 本地标签差异化
NASM local label differentiation
据我了解,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 是否比这更聪明并使用其他方法来决定在任何给定时间哪个标签处于活动状态?
根据YASM's docs on NASM local labels,局部标签与全局标签相关联。所以我认为如果没有全局标签分隔 .fin
.
的两个实例,你的示例实际上会发生冲突
实际上,这种理解并不完全正确。本地标签不是独立的项目,它们实际上与最近的非本地标签相关联。
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
是行不通的,因为那样会 select part1.fin
,但是完全限定的 part2.fin
就可以了。
At the point where jz .fin
in the second loop is assembled, surely the earlier instance of .fin
would still be active and it would jump to the wrong location.
Or is NASM smarter than that and uses some other method to decide which label is active at any given time?
让我们一探究竟!
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
的第二个实例。
据我了解,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 是否比这更聪明并使用其他方法来决定在任何给定时间哪个标签处于活动状态?
根据YASM's docs on NASM local labels,局部标签与全局标签相关联。所以我认为如果没有全局标签分隔 .fin
.
实际上,这种理解并不完全正确。本地标签不是独立的项目,它们实际上与最近的非本地标签相关联。
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
是行不通的,因为那样会 select part1.fin
,但是完全限定的 part2.fin
就可以了。
At the point where
jz .fin
in the second loop is assembled, surely the earlier instance of.fin
would still be active and it would jump to the wrong location.Or is NASM smarter than that and uses some other method to decide which label is active at any given time?
让我们一探究竟!
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
的第二个实例。