我试图在汇编程序中设置一些指针(在x86_64 linux上运行的AT& t语法(,然后将它们传递给C程序以实质上添加其值。当然,这并不是要实现最终结果的最有效方法,但是我试图了解如何使这样的事情起作用以进一步构建它。C程序如下:
#include <stdio.h>
extern void iplus(long *a, long *b, long *c){
printf("Startingn");
long r= *a + *b;
printf("R setupn");
*c=r;
printf("Donen");
}
这需要三个长指针,添加了前两个的值,然后在第三个值中存储该值。如上所示,它在每个点上打印一条有关其状态的消息,以跟踪分割故障的位置。
引用此功能的汇编程序如下:
.extern exit
.extern malloc
.data
vars: .zero 24 /*stores pointer addresses*/
.text
FORI: .ascii "%d " /*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;
中的第一个操作或较早的事物中仅成为问题的某些操作正在引起segfault。我期望发生的是,对于24字节vars
持有的三个8字节值,malloc
返回的地址(每次分配8个字节(存储。然后,该地址指向一个8字节整数,该整数设置为3、7和0。这些整数的地址(即vars
中持有的值(将传递给iplus
以概括它们,然后总和为使用printf
打印。由于某种原因我无法识别,这会导致segfault。
为什么要出现segfault?是否可以使用C函数调用与基本上仍然使用的双指针的结构执行此添加?
您不能直接使用位于内存中的指针,应首先将其加载到寄存器中。您放置的双括号只是被忽略的,所以这是:
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)