I am attempting to set up some pointers in an assembly program(AT&T syntax running on x86_64 linux), then pass them to a C program to essentially add their values. Of course, this isn't the most effective way of accomplishing the end result, but I'm trying to understand how to make something like this work in order to further build off of it. The C program looks as follows:
#include <stdio.h>
extern void iplus(long *a, long *b, long *c){
printf("Starting\n");
long r= *a + *b;
printf("R setup\n");
*c=r;
printf("Done\n");
}
This takes three long pointers, adds the value of the first two, then stores that value in the third. As shown above, it prints a message regarding its status at each point, in order to track where the segmentation fault occurs.
The assembly program referencing this function is as follows:
.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
Upon making then executing the above program, I get this output:
Starting
Segmentation fault (core dumped)
Meaning the function seems to be successfully called, but something about the first operation within that function, long r = *a + *b;
, or something earlier that only becomes a problem at that point, is causing a segfault. What I expect to happen is that, for the three 8-byte values held by the 24-byte vars
, the address returned by malloc
(which allocates 8 bytes each time), is stored. This address then points to an 8-byte integer, which are set to 3, 7, and 0. The addresses of these integers(i.e. the values held in vars
), are passed to iplus
in order to sum them, then the sum is printed using printf
. For a reason I cannot identify, this instead causes a segfault.
Why is the segfault occurring? Is it possible to perform this addition using the C function call with the structure of basically a double pointer still being used?
You can't use pointer residing in memory directly, you should first load it into register. Double parentheses you put are just ignored, so this:
movq $3,((vars+0)) /*first addend 3*/
movq $7,((vars+8)) /*second addend 7*/
movq $0,((vars+16))
is the same as this:
movq $3,(vars+0) /*first addend 3*/
movq $7,(vars+8) /*second addend 7*/
movq $0,(vars+16)
Instead you need to do (for each value):
movq (vars+0), %rax
movq $3, (%rax)