Assembly 使用命名变量运行asm程序时的延迟
我有以下程序将两个数字相乘:Assembly 使用命名变量运行asm程序时的延迟,assembly,x86-64,att,Assembly,X86 64,Att,我有以下程序将两个数字相乘: .globl main main: # Store the two numbers temporarily in ebx, ecx mov $7, %ebx mov $14, %ecx # clear out eax and add ebx (7) to it ecx (14) times mov $0, %eax multiply_step: add %ebx, %eax dec
.globl main
main:
# Store the two numbers temporarily in ebx, ecx
mov $7, %ebx
mov $14, %ecx
# clear out eax and add ebx (7) to it ecx (14) times
mov $0, %eax
multiply_step:
add %ebx, %eax
dec %ecx
jnz multiply_step
ret
然而,如果出于任何原因为14和7添加变量,程序运行大约需要一秒钟,这似乎有点奇怪,上面的程序是瞬时的-
.globl main
.globl x,y
x: .byte 7
y: .byte 14
main:
mov x, %ebx
mov y, %ecx
mov $0, %eax
multiply_step:
add %ebx, %eax
dec %ecx
jnz multiply_step
ret
为什么这个程序运行时间更长?我援引这两种说法是:
$ gcc m2.s -o m2 && ./m2; echo $?
# 98
变量x是一个字节,但将4个字节移动到ebx中,因此ebx的值不是7。加载到ebx中的实际值为0x1d8b0e07。类似地,ecx中的值类似于0x011d8b0e,因此您可以了解为什么循环比0x0e长得多 尽管有此错误,结果的低位字节是相同的 要将这些字节值加载到32位寄存器中,请使用:
movzbl x, %ebx
movzbl y, %ecx
此指令从内存中读取一个字节,零将其扩展到32位,并将结果放入目标寄存器
或者像您在其他问题中使用的那样,在64位代码中,RIP相对寻址更有效,并且可以在现代的PIE可执行文件中使用:
movzbl x(%rip), %ebx
movzbl y(%rip), %ecx
可以使用调试器查看寄存器中的值;这是一种简单的方法,可以清楚地了解此处发生的情况。您如何知道ebx中的值是0x1d8b0e07,或者您只是在编一个以07结尾的数字?不,当然我永远不会这样做!:-不过,我没有完全理解它,因为我不知道这是64位代码。它应该是0x1c8b0e07。x后面的下一个字节是y,即14。接下来的两个字节是main的第一条指令mov x,%ebx的前两个字节,在64位模式下为8b 1c 25 xxxxxxxx,其中xxxxxxxx是x的地址。如果它是32位代码,那么它将是8b 1d xxxxxxxx。太棒了,谢谢。出于好奇,你是如何自学组装并学得这么好的?似乎有太多的途径不同于像学习python这样更简单/主流的人