刚开始使用汇编(GAS),并且在这个短代码中有分段错误
Posted
技术标签:
【中文标题】刚开始使用汇编(GAS),并且在这个短代码中有分段错误【英文标题】:Just start using assembly (GAS), and has segmentation fault in this short code 【发布时间】:2017-05-09 08:23:44 【问题描述】:这些天我正在学习 AT&T x86 组装。我正在编写将两个 32 位整数相乘而不使用“*”的代码。问题是调试器一直告诉我我有分段错误。这是我的代码。
.global _start
.data
a:
.long 0
b:
.long 0
count:
.long 0
.text
_start:
movl $0, %eax
movl $a, %ebx
movl $b, %ecx
movl $0, %edx
for_mult:
cmpl $32, count
je end_for_mult
carry_bit:
shr $1, %ecx
jnc is_zero
addl (%ebx), %eax
is_zero:
shl $1, %ebx
incl count
jmp for_mult
end_for_mult:
done:
movl %eax, %eax
调试器显示段错误出现在“addl (%ebx), %eax”,我不知道为什么。感谢您的帮助!
【问题讨论】:
您应该考虑shl $1, %ebx
对ebx
的作用以及在下一轮 循环中这会如何影响addl (%ebx), %eax
。
当调试器出现分段错误并指向某个指令时,您可以检查所使用的内存地址(在这种情况下为ebx
中的值)。然后你可以检查你分配的内存(通常是.data
/.rodata
部分标签),如果它指向你想要的地方。然后您可以开始搜索(可能通过一次执行代码 1 指令),为什么您离开了有效/预期的内存。顺便说一句,你还有一些免费的寄存器,为什么不为count
也使用一个呢?实际上为什么不只使用寄存器,并将结果存储到内存中呢?它通常更容易+更快。
【参考方案1】:
您正在混合地址和值。
把$符号去掉
movl a, %ebx
movl b, %ecx
(您的代码实际上将a
和b
的地址移动到寄存器而不是值!)
去掉%ebx
周围的括号
addl %ebx, %eax
你想要的是 ebx 的值,而不是 ebx 指向的值。
【讨论】:
以上是关于刚开始使用汇编(GAS),并且在这个短代码中有分段错误的主要内容,如果未能解决你的问题,请参考以下文章
在 x86 汇编代码(GAS 语法)中有效乘以 2 的幂而不影响标志
为啥包装在函数中的 GAS 内联汇编为调用者生成的指令与纯汇编函数不同