【发布时间】:2020-01-03 15:29:34
【问题描述】:
我已尝试在网上搜索此内容,但没有找到任何答案。我正在研究汇编条件跳转并正在使用这个 C 例程:
long absdiff (long x, long y) {
long result;
if (x > y)
result = x-y;
else
result = y-x;
return result;
}
我的笔记说它返回一个类似这样的 asm 代码:
absdiff:
cmpq %rsi, %rdi
jle .L4
movq %rdi, %rax
subq %rsi, %rax
ret
.L4:
movq %rsi, %rax
subq %rdi, %rax
ret
据我所知,如果x <= y,例程将跳转到.L4,然后从该跳转返回到下一条指令并继续直到ret,我知道这是错误的。由于%rax 是用.L4 编写的,我认为它的ret 适用于整个例程,而不是跳转到的那个,但我在使用gdb 调试C 例程时也看到了类似这样的代码:
0x1119 <absdiff> mov %rdi,%rax
0x111c <absdiff+3> cmp %rsi,%rdi
0x111f <absdiff+6> jle 0x1125 <absdiff+12>
0x1121 <absdiff+8> sub %rsi,%rax
0x1124 <absdiff+11> retq
0x1125 <absdiff+12> sub %rdi,%rsi
0x1128 <absdiff+15> mov %rsi,%rax
0x112b <absdiff+18> retq
在这里,我了解到例程在不同的点上返回,就像您在 C 例程上编写不同的返回一样。所以我的问题是:汇编语言中.LX 例程标记的含义是什么,与它们跳转到的例程有什么关系?
【问题讨论】:
-
如果满足比较或采用其他代码路径,则代码进行比较跳转一个代码路径是 return x - y 另一个是 return y - x,看起来很好,有什么问题? LX 是为编译器生成的汇编语言创建的标签,它是一个通用标签名称,理想情况下不会与用户标签冲突,为了进行跳转,汇编语言需要一个通常使用标签而不是绝对偏移量的目的地,让汇编器找出偏移量。
-
代码运行良好,但我不明白
.L4与absdiff的关系如何。我什么时候应该写一个.LX例程,什么时候应该写一个不同的例程?.L4是absdiff的一部分吗? -
这些是标签,而不是标签。处理器不知道什么是例程。跳转到给定地址,仅此而已。
-
在这种情况下反汇编时,反汇编程序和/或二进制文件不再保留 .L4 标签,因此在这种情况下使用最近的标签和偏移量。一个可以产生另一个,如果它被编译,可能会产生。 .L 之后的数字取决于当时该代码中有多少标签,汇编器会不断生成唯一的标签。
-
我不知道它是否是点,我怀疑,但如果您自己编写该代码并使用您自己的标签 foo_bar:标签很可能在二进制文件和反汇编程序中会使用它而不是 absdiff
标签: assembly x86 subroutine