本文最后更新于:2022年9月4日 下午
程序员视角
- 程序计数器(Program counter,PC )
- 寄存器(Register)
- 条件码(Condition codes)
- 内存(Memory)
- 可按字节寻址的数组(内存就是个大数组)
- 程序和数据
- 栈(Stack,用于函数调用过程的实现)
几种常见的寻址方式
寄存器间接寻址
寄存器R指定内存地址
相对寻址
- 寄存器R指定内存区域的开始地址,需配合偏移地址
- 形式:D(R) 含义:Mem[Reg[R]+D] D为1/2/4/8
完整的内存寻址模式
- D(Rb,Ri,S)
- Mem[Reg[Rb]+S*Reg[Ri]+ D]
(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]]
D(Rb,Ri) Mem[Reg[Rb]+Reg[Ri]+D]
(Rb,Ri,S) Mem[Reg[Rb]+S*Reg[Ri]]
mov对应的C语言语句
movq $0x4,%rax
movq $-147, (%rax)
movq %rax, %rdx
movq %rax, (%rdx)
movq (%rax), %rdx
swap函数
1 2 3 4 5 6 7 8
| void swap (long *xp, long *yp) { long t0 = *xp; long t1 = *yp; *xp = t1; *yp = t0; }
|
对应汇编:
1 2 3 4 5 6
| swap: movq (%rdi), %rax # t0 = *xp movq (%rsi), %rdx # t1 = *yp movq %rdx, (%rdi) # *xp = t1 movq %rax, (%rsi) # *yp = t0 ret
|
C语言程序与汇编的转换
C语言程序:
1 2 3 4 5 6 7
| long plus(long x, long y); void sumstore(long x, long y, long *dest) { long t = plus(x, y); *dest = t; }
|
生成的汇编:
Assembly1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| .file "fk.c" .text .globl sumstore .type sumstore, @function sumstore: .LFB0: .cfi_startproc endbr64 pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movq %rdx, %rbx call plus@PLT movq %rax, (%rbx) popq %rbx .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE0: .size sumstore, .-sumstore .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" .section .note.GNU-stack,"",@progbits .section .note.gnu.property,"a" .align 8 .long 1f - 0f .long 4f - 1f .long 5 0: .string "GNU" 1: .align 8 .long 0xc0000002 .long 3f - 2f 2: .long 0x3 3: .align 8 4:
|
精简一下:
Assembly1 2 3 4 5 6 7
| sumstore: pushq %rbx movq %rdx, %rbx call plus movq %rax, (%rbx) popq %rbx ret
|
可以使用objdump
对二进制文件进行反汇编
1 2 3 4 5 6 7 8 9 10 11 12 13
| objdump
View information about object files. More information: https:
- Display the file header information: objdump -f binary
- Display the dis-assembled output of executable sections: objdump -d binary
- Display a complete binary hex dump of all sections: objdump -s binary
|