1

I need to pass address instead of value of my field from C to assembly function, and I have no idea why I end up with value instead of address.

C code:

long n = 1,ret = 0;
fun(&n, &ret);
//the rest is omitted

Assembly code:

.globl fun
fun:

pushq %rbp
movq %rsp, %rbp

movq 16(%rbp), %rax #my n address
movq 24(%rbp), %rbx #my ret address

cmpq $0, %rax
//the rest is omitted

When I peek values of %rax and %rbx with gdb I can see that I have values in my registers:

Breakpoint 1, fun () at cw.s:6
6       movq 16(%rbp), %rax #my n address
(gdb) s
7       movq 24(%rbp), %rbx #my ret address
(gdb) s
9       cmpq $0, %rax
(gdb) p $rax
$1 = 1
(gdb) p $rbx
$2 = 0

I don't really see whats wrong with my code. I'm sure that &n makes C pass address instead of value. I am following the solution provided here, but with no luck.

Calling a C function in assembly

Update:

I'm running LXLE (it's a fork of Ubuntu) on AMD x86_64. The compiler used is gcc (Ubuntu 4.8.2-19ubuntu1) and GNU assembler (GNU Binutils for Ubuntu) 2.24. My makefile:

cw: cw.c cw.o
    gcc cw.o cw.c -o cw
cw.o: cw.s
    as -gstabs -o cw.o cw.s
Community
  • 1
  • 1
Praeterii
  • 340
  • 6
  • 16
  • 2
    What is your function definition? This is just the call. If your definition contains int, there may be implicit pointer to int conversion. – Pieter21 Apr 29 '15 at 08:12
  • 2
    I'd put a breakpoint in the C code, and then look at the assembly that the compiler generated. My guess is that you added the `&`s to the code as an afterthought and somehow forgot to recompile the C code. – user3386109 Apr 29 '15 at 08:25
  • 1
    Try `info registers` instead of `p $rax`.. – Jabberwocky Apr 29 '15 at 08:27
  • What if I dont have any declaration/definition about function fun in C? – Praeterii Apr 29 '15 at 08:52

1 Answers1

3

What architecture are you on? What compiler generated the code for fun? Did you write it yourself?

The code is using the r* registers and your question mentions "x64", so I would assume it's some amd64/x86-64/x64 architecture. You're reading things from the stack (which you've commented as "my n/ret address") which I would assume that you expect the function arguments to be there but I'm not aware of any ABI on that CPU family that passes the first arguments to a function on the stack.

If you wrote it yourself, you need to read up on the calling conventions of the ABI your operating system/compiler uses, because unless you're on a very obscure operating system it will not pass (the first few) function arguments on the stack. Most likely you're just reading random values from the stack that just happen to match where your compiler happened to put the values in the calling function.

If you're on Linux or most other unix-like system that use the SysV ABI the first two arguments to a function will be in the rdi, rsi registers. If you're on Windows, that will be rcx, rdx. This is assuming that your arguments are int/long/pointers. If the arguments are structs, floating point or such, other rules apply.

Art
  • 19,807
  • 1
  • 34
  • 60
  • 1
    The SysV x86-64 ABI, as used by Linux: http://www.x86-64.org/documentation/abi.pdf – caf Apr 29 '15 at 08:46