Segfault从汇编​​中调用c函数

时间:2018-02-05 21:30:37

标签: c assembly segmentation-fault x86-64 function-calls

我试图在汇编程序中设置一些指针(在x86_64 linux上运行AT& T语法),然后将它们传递给C程序以实质上添加它们的值。当然,这不是实现最终结果的最有效方法,但我正在努力了解如何制作类似这样的工作以进一步构建它。 C程序如下:

.extern exit
.extern malloc
.data
vars: .zero 24 /*stores pointer addresses*/
.text
FORI: .ascii "%d\0" /*format for printing integer*/
.global main
main:
and $~0xf, %rsp /*16-byte align the stack*/
movq $8,%rdi
call malloc
movq %rax,(vars+0) /*allocate 8 bytes and put its address into the variable*/
movq $8,%rdi
call malloc
movq %rax,(vars+8)
movq $8,%rdi
call malloc
movq %rax,(vars+16)
movq $3,((vars+0)) /*first addend 3*/
movq $7,((vars+8)) /*second addend 7*/
movq $0,((vars+16))
movq (vars),%rdi
movq (vars+8),%rsi
movq (vars+16),%rdx
call iplus /*call the function with these values*/
movq $FORI,%rdi
movq ((vars+16)),%rsi
call printf /*print the sum, "10" expected*/
call exit

这需要三个长指针,添加前两个的值,然后将该值存储在第三个中。如上所示,它会在每个点打印有关其状态的消息,以便跟踪分段故障发生的位置。

引用此功能的汇编程序如下:

Starting
Segmentation fault (core dumped)

在执行上述程序后,我得到了这个输出:

long r = *a + *b;

这意味着函数似乎被成功调用,但是关于该函数中的第一个操作vars,或之前仅在此时成为问题的某些操作,导致了段错误。我期望发生的是,对于由24字节malloc保存的三个8字节值,存储由vars(每次分配8个字节)返回的地址。然后该地址指向一个8字节的整数,设置为3,7和0.这些整数的地址(即iplus中保存的值)按顺序传递给printf总结它们,然后使用VString打印总和。由于我无法识别的原因,这会导致段错误。

为什么会出现段错误?是否可以使用C函数调用执行此添加,基本上仍然使用双指针的结构?

1 个答案:

答案 0 :(得分:2)

你不能直接使用驻留在内存中的指针,你应该先将它加载到寄存器中。你放的双括号只是被忽略了,所以这个:

movq $3,((vars+0)) /*first addend 3*/
movq $7,((vars+8)) /*second addend 7*/
movq $0,((vars+16))

与此相同:

movq $3,(vars+0) /*first addend 3*/
movq $7,(vars+8) /*second addend 7*/
movq $0,(vars+16)

相反,您需要(对于每个值):

movq (vars+0), %rax
movq $3, (%rax)