This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How can I do calling for external address in my "C" programm by inline GAS?


Joe Abbey wrote:
> Presuming you're building this for Linux, I highly recommend you read the
> 64-bit ABI.
> 
> http://www.x86-64.org/documentation/abi.pdf
> 
> Chapter 3 is your friend.  There's a lot of details there, hand-rolling
> 64-bit assembly is more complicated than 32-bit.  There are things like
> red-zone, which you're writing into with the pushq.  And since you probably
> won't read the ABI, here's fixed source:
> 
> #include <stdio.h>
> 
> int main(){
> 
> void *p_printf = (void *)&printf;
> const char *str = "Hello\n";
> 
> printf("addr of printf=%p\n", &printf); // 0x400490
> 
> asm ("movq %0, %%rdi;" /* str into RDI */
>     "leaq (, %1), %%rcx;" /* address of PRINTF into RCX */
>     "call * %%rcx;" /* call PRINTF */
> 
>  :  /* output */
>  :
>  :"r"(str),"r"(p_printf)         /* input */
>  :
>  : "rdi", "rcx"
> 
> );
> 
> return 0;
> }
> 
> Nota Bene: The Windows 64-bit ABI is completely different, so while this
> source may compile and work on Linux... it will not work for Windows.
> 
> Cheers,
> 
> Joe


Hi Joe!

Thank you for link on documentation of abi amd64.

Could you explain me, what I'm doing wrong now, maybe my cpu is broken ?:


++++++++++++++++++++++++++++++++++++++++++++++++++
user@localhost ~/ $ gdb ./call64
GNU gdb (Gentoo 7.3.1 p2) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.gentoo.org/>...
Reading symbols from /home/user/call64...done.




(gdb) list 1,27
1       #include <stdio.h>
2
3       static void *p_printf = (void *)&printf;
4       static const char *str = "Hello\n";
5
6       void exec_printf(){
7       asm volatile (
8           "movq %0, %%rcx;" /* str into RCX is first integer argument (amd64 
notation) */
9           "movq %1, %%rdi;" /* address of PRINTF into RDI is Must be 
preserved by called function (amd64 notation) */
10          "call * %%rdi;" /* call PRINTF */
11       :  /* no output */
12       :"r"(str),"r"(p_printf)         /* input */
13       : "rcx", "rdi", "memory" /* clobbered register */
14      );
15      }
16
17      // gcc -g -m64 call64.c -o call64 && ./call64
18      int main(){
19
20      printf("\n[addr of printf: %p]\n", &printf); // 0x400438
21      printf("[addr of str: %p]\n", str); // 0x40069c
22
23      exec_printf();
24
25      return 0;
26      }





(gdb) display/x $rcx, $rdi
(gdb) run
Starting program: /home/user/call64 

[addr of printf: 0x400438]
[addr of str: 0x40069c]

Program received signal SIGSEGV, Segmentation fault.
0x00000000004005a7 in main () at call64.c:26
26      }
1: /x $rcx, $rdi = 0x400438




(gdb) disas exec_printf
Dump of assembler code for function exec_printf:
   0x0000000000400544 <+0>:     push   %rbp
   0x0000000000400545 <+1>:     mov    %rsp,%rbp
   0x0000000000400548 <+4>:     mov    0x200ad9(%rip),%rax        # 0x601028 
<str>
   0x000000000040054f <+11>:    mov    0x200aca(%rip),%rdx        # 0x601020 
<p_printf>
   0x0000000000400556 <+18>:    mov    %rax,%rcx
   0x0000000000400559 <+21>:    mov    %rdx,%rdi
   0x000000000040055c <+24>:    callq  *%rdi
   0x000000000040055e <+26>:    leaveq 
   0x000000000040055f <+27>:    retq   
End of assembler dump.

++++++++++++++++++++++++++++++++++++++++++++++++++


-- 
The best Regards.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]