at&a 64汇编

 

1.第一个at&a 64汇编

  1 .section    .data
  2 strFormat:
  3 .asciz "%s\n"
  4 strUseLibc:
  5 .asciz "Hi, If you see me, you called c lib :)"
  6 strUseSyscall:
  7 .asciz "And if you see me, you called syscall.\n"
  8 endOfStrUseSyscall:
  9 
 10 .section    .text
 11 .globl  _start
 12 _start:
 13 # 函数调用的传参已经不再单纯使用压栈的方式
 14 movq    $strFormat, %rdi
 15 movq    $strUseLibc, %rsi
 16 call    printf
 17 
 18 # 系统调用的寄存器已经改变,int 0x80 也被syscall 替代
 19 movq    $1, %rdi
 20 movq    $strUseSyscall, %rsi
 21 movq    $(endOfStrUseSyscall-strUseSyscall), %rdx
 22 movq    $1, %rax
 23 syscall
 24 
 25 #另外系统调用的编号也不同了
 26 movq    $127, %rdi      # 故意返回一个非0 值
 27 movq    $60, %rax
 28 syscall

 

2 从c 转成汇编,再编译成bin 

GCC 编译的背后

http://tinylab.org/behind-the-gcc-compiler/

1 #include <stdio.h>
2 #include <unistd.h>
3 
4 int  sum(int a) {
5         return a;
6 }
7 int main() {
8         int b = 0;
9         b = sum(1);
10        printf("hello:%d\n", b);
11        _exit(0);
12 }
1 gcc -S  test.c -fno-asynchronous-unwind-tables -fno-exceptions -fno-stack-protector
2 sed -i -e "s#main#_start#g" test.s
3 gcc -c test.s
4 #ld -o test test.o   /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o  -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2
5 ld -o test test.o   -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2

 

gcc -S  test.c


  1         .file   "test.c"
  2         .text
  3         .globl  sum
  4         .type   sum, @function
  5 sum:
  6 .LFB0:
  7         .cfi_startproc
  8         pushq   %rbp
  9         .cfi_def_cfa_offset 16
 10         .cfi_offset 6, -16
 11         movq    %rsp, %rbp
 12         .cfi_def_cfa_register 6
 13         movl    %edi, -4(%rbp)
 14         movl    -4(%rbp), %eax
 15         popq    %rbp
 16         .cfi_def_cfa 7, 8
 17         ret
 18         .cfi_endproc
 19 .LFE0:
 20         .size   sum, .-sum
 21         .section        .rodata
 22 .LC0:
 23         .string "hello:%d\n"
 24         .text
 25         .globl  main
 26         .type   main, @function
 27 main:
 28 .LFB1:
 29         .cfi_startproc
 30         pushq   %rbp
 31         .cfi_def_cfa_offset 16
 32         .cfi_offset 6, -16
 33         movq    %rsp, %rbp
 34         .cfi_def_cfa_register 6
 35         subq    $16, %rsp
 36         movl    $0, -4(%rbp)
 37         movl    $1, %edi
 38         call    sum
 39         movl    %eax, -4(%rbp)
 40         movl    -4(%rbp), %eax
 41         movl    %eax, %esi
 42         movl    $.LC0, %edi
 43         movl    $0, %eax
 44         call    printf
 45         movl    $0, %edi
 46         call    _exit
 47         .cfi_endproc
 48 .LFE1:
 49         .size   main, .-main
 50         .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609"
 51         .section        .note.GNU-stack,"",@progbits
.cfi_startproc
.cfi_def_cfa_offset
.cfi_def_cfa_register
.cfi_def_cfa 
.cfi_def_cfa

这些指令叫 cfi 指令,https://cloud.tencent.com/developer/ask/102663 具体用法先不用管。
c 可用 -fno-asynchronous-unwind-tables gcc选项去除,这样方便我们看代码
cpp 必须
-fno-asynchronous-unwind-tables -fno-exceptions 一起用才能去除
movq    %fs:40, %rax
xorq    %fs:40, %rdx
可用 -fno-stack-protector 去除

  1         .file   "test.c"
  2         .text
  3         .globl  sum
  4         .type   sum, @function
  5 sum:
  6         pushq   %rbp
  7         movq    %rsp, %rbp
  8         movl    %edi, -4(%rbp)                   
  9         movl    -4(%rbp), %eax                   
 10         popq    %rbp                             
 11         ret
 12         .size   sum, .-sum
 13         .section        .rodata                  
 14 .LC0:   
 15         .string "hello:%d\n"                     
 16         .text
 17         .globl  main
 18         .type   main, @function                  
 19 main:   
 20         pushq   %rbp
 21         movq    %rsp, %rbp                       
 22         subq    $16, %rsp
 23         movl    $0, -4(%rbp)                     
 24         movl    $1, %edi                         
 25         call    sum
 26         movl    %eax, -4(%rbp)                   
 27         movl    -4(%rbp), %eax                   
 28         movl    %eax, %esi
 29         movl    $.LC0, %edi                      
 30         movl    $0, %eax                         
 31         call    printf
 32         movl    $0, %edi                      
 33         call    _exit
 34         .size   main, .-main
 35         .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609"
 36         .section        .note.GNU-stack,"",@progbits

 堆栈平衡

https://www.cnblogs.com/mysqlinternal/p/12737841.html

 

.rodata  ro代表read only,即只读数据(const)。

字符串长度

msg: .string "Hello,world!\n"#要输出的字符串

len=. -msg #字串长度

用户自定义section 

static int __attribute__((section(".xinit"))) hello() {  

  printf("abc");

}

18 .section .xinit,"ax",@progbits
19 .type hello, @function
20 hello:
21 pushq %rbp
22 movq %rsp, %rbp
23 movl $.LC0, %edi
24 movl $0, %eax
25 call printf
26 nop
27 popq %rbp
28 ret
29 .size hello, .-hello
.section .xinit,"ax",@progbits
.section name [, "flags"[, @type[,flag_specific_arguments]]]
https://sourceware.org/binutils/docs/as/Section.html
http://web.mit.edu/rhel-doc/3/rhel-as-en-3/section.html



call printf 前有movl $0, %eax
https://stackoverflow.com/questions/6212665/why-is-eax-zeroed-before-a-call-to-printf 



posted @ 2020-04-20 10:46  通杀  阅读(291)  评论(0编辑  收藏  举报