【发布时间】:2018-04-02 19:20:48
【问题描述】:
所以,我有一个汇编函数,它在 C 中调用。它编译并且不给我任何警告,但是当我尝试运行它时,它给我一个分段错误。我认为这是因为我无法将常量移动到寄存器中,但是要使用 mul/div 命令,它需要一个值在 EAX 寄存器中。 如何在 Assembly 中将两个常数相乘或相除?
这是目前为止的代码...
.section .data
.global n
.equ A, 50
.equ B, 5
.section .text
.global loop_function
loop_function:
# prologue
pushl %ebp # save previous stack frame pointer
movl %esp, %ebp # the stack frame pointer for sum function
# beginning
movl i, %ebx # place i (declared in c) in ebx
movl A, %eax # place A in eax
movl B, %ecx # place B in ecx
jmp loop
loop:
movl $0, %edx # clean edx register
cdq
idivl %ecx # A / B, result in eax
imull %ebx # i * A / B, result in eax
incl %ebx
cmpl %ebx, n # if i <= n
jle loop # then jumps to loop
jmp end # else jumps to end
end:
# epilogue
movl %ebp, %esp # restore the previous stack pointer ("clear" the stack)
popl %ebp # restore the previous stack frame pointer
ret
【问题讨论】:
-
真正的答案在Application_binary_interface (ABI) 中。如果您没有 ABI,那么我建议将您使用的每个寄存器都推入堆栈,并在返回之前将其弹出。
-
错误的可能原因是您没有遵循标准调用约定。特别是,您销毁了
ebx,它是一个被调用者保存的寄存器,因此您的调用者很可能希望它保持不变。 -
A 和 B 似乎是常量,我猜 i 是一个变量,但您对它们都使用完全相同的语法。我认为它正在尝试从内存地址 50 和地址 5 加载值,这是行不通的。我建议使用 $A 和 $B。
-
如果我把 $50 和 $5 放在常量的声明中,编译失败,我认为 $A 给出了常量的内存地址。
-
您将常量声明为内存地址,因此您应该使用
$A和$B。你试过了吗?为了能够使用A,您需要类似:A: .int 50。
标签: assembly x86 constants gnu-assembler att