Question

And where is the result stored? I read that it is typically %eax, but a 64-bit uint is too wide for that. I can't find the result in the stack either.

% clang --version
Debian clang version 3.1-3eudoxos1 (branches/release_31) (based on LLVM 3.1)
Target: i386-pc-linux-gnu
Thread model: posix

Clang input (UPDATED, signature now corresponds to name):

% cat stackoverflow.c                                  
unsigned long long double2ulonglong(double a) {
    return a;
}

Compilation and disassembly (UPDATED, relocation info added. Now uses fixuns*d*fdi.):

% clang -g -Os -c stackoverflow.c && objdump -d -r stackoverflow.o
00000000 <double2ulonglong>:
   0:   83 ec 0c                sub    $0xc,%esp
   3:   f2 0f 10 44 24 10       movsd  0x10(%esp),%xmm0
   9:   f2 0f 11 04 24          movsd  %xmm0,(%esp)
   e:   e8 fc ff ff ff          call   f <double2ulonglong+0xf>
            f: R_386_PC32   __fixunsdfdi
  13:   83 c4 0c                add    $0xc,%esp
  16:   c3                      ret

Main procedure (assembly):

% cat main.s                                                   
.data
    a: .double 6.283045
.text
.globl main
main:
    pushl a+4
    pushl a
    call double2ulonglong
    addl $8, %esp
    ret

Assembly:

% as -g -o main.o -c main.s                            

Linking:

% gcc -g -o executableelf stackoverflow.o main.o       

Debugging:

% gdb executableelf                             
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Reading symbols from /home/janus/asmplay/conv/executableelf...done.
(gdb) start
Temporary breakpoint 1 at 0x80483cc: file main.s, line 6.
Starting program: /home/janus/asmplay/conv/executableelf 

Temporary breakpoint 1, main () at main.s:6
6       pushl a+4
(gdb) list
1   .data
2       a: .double 6.283045
3   .text
4   .globl main
5   main:
6       pushl a+4
7       pushl a
8       call double2ulonglong
9       addl $8, %esp
10      ret
(gdb) break 8
Breakpoint 2 at 0x80483d8: file main.s, line 8.
(gdb) c
Continuing.

Breakpoint 2, main () at main.s:8
8       call double2ulonglong
(gdb) stepi
0x080483b4 in double2ulonglong (a=-1.9971046447753908)
(gdb) disass
Dump of assembler code for function double2ulonglong:
=> 0x080483b4 <+0>: sub    $0xc,%esp
   0x080483b7 <+3>: movsd  0x10(%esp),%xmm0
   0x080483bd <+9>: movsd  %xmm0,(%esp)
   0x080483c2 <+14>:    call   0x80483f0 <__fixunsdfdi>
   0x080483c7 <+19>:    add    $0xc,%esp
   0x080483ca <+22>:    ret    
End of assembler dump.
(gdb) break *($eip+19)
Breakpoint 3 at 0x80483c7: file stackoverflow.c, line 2.
(gdb) c
Continuing.

Breakpoint 3, 0x080483c7 in double2ulonglong (a=6.2830450000000004) at stackoverflow.c:2
2       return a;
(gdb) x/16x $esp
0xbffff374: 0x8c692f6f  0x401921d6  0xb7fb9ff4  0x080483dd
0xbffff384: 0x8c692f6f  0x401921d6  0xb7e324d3  0x00000001
0xbffff394: 0xbffff424  0xbffff42c  0xb7fdc858  0x00000000
0xbffff3a4: 0xbffff41c  0xbffff42c  0x00000000  0x0804820c
(gdb) 

EDIT: Fix signature in C function, show disassembly after linking.

Remaining questions:

  • Why is the unsigned int 6 nowhere in the stack?
    • Answer: It is in %eax.
Was it helpful?

Solution

You're looking at the contents of an object file which has not been linked yet, so external references have not been resolved. The function is probably calling some compiler helper and the call will be resolved at the link time. If you add the -r switch to objdump, it will print the relocation info at the call site.

As for the result, the convention on i386 is to use edx:eax pair for returning 64-bit integers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top