先举例说如何访问C代码里的变量
c.c
  1. int c_int = 13;
  2. char *c_str = "hello, world#";
main.asm
  1. extern c_int;
  2. extern c_str;
  3.  
  4. section .data
  5. message:
  6.     db 'hello, world!', 0
  7. section .text
  8. global _start
  9. _start:
  10.     mov rax, 4
  11.     mov rdi, 1
  12.     mov rsi, [c_str]
  13.     mov rdx, [c_int]
  14.     syscall
  15.     mov rax, 1
  16.     xor rdi, rdi
  17.     syscall
挺简单的,就是在asm代码里extern导出这变量,就可以用了,但需要注意的是,c_str是指针这个变量的地址,
不是字符串的地址,所以要[]括起来。同样c_int也不能直接用。

下面举例如何在c代码和asm代码里互调函数
c.c
  1. #include <stdio.h>

  2. extern void asm_print();
  3. void my_print(const char* str){
  4.     asm_print(str);
  5. }
main.asm
  1. extern my_print

  2.         section .data
  3. message:
  4.     db 'hello, world!', 0
  5. section .text
  6. global asm_print
  7. asm_print:
  8.     push rbp
  9.     mov rbp, rsp
  10.     mov r8, rdi
  11.     mov rax, 4
  12.     mov rdi, 1
  13.     mov rsi, r8
  14.     mov rdx, 13
  15.     syscall
  16.     leave
  17.     ret
  18. global _start
  19. _start:
  20.     mov rdi, message
  21.     call my_print
  22.     mov rax, 1
  23.     xor rdi, rdi
  24.     syscall
汇编代码里如果想对外可见,则加个global修饰。
前面提到过第一个参数是通过rdi传入的,我们临时存储到r8里,因为rdi在调用syscall的时候还需要用,不能覆盖了。
这里为啥r8不需要[]了呢,我的解释是,rdi寄存器装的就是地址。

note:调用leave指令和调用下面的是一个结果,都是恢复栈顶和ebp
  1. mov esp,ebp
  2. pop ebp



09-06 02:23