2020-2021-1 20209318《Linux内核原理与分析》第二周作业
2020-2021-1 20209318《Linux内核原理与分析》第二周作业
汇编基础
Intel 处理器系列也称为x86,32位的体系结构称为IA32,64位体系结构称为x86-64。
IA32所含有的寄存器包括:
- 4个数据寄存器(EAX EBX ECX EDX)
- 2个变址和指针寄存器(ESI EDI)
- 2个指针寄存器(ESP EBP)
- 6个段寄存器(ES CS SS DS FS GS)
- 1个指令指针寄存器(EIP)
- 1个标志寄存器(EFlags)
汇编指令包含操作码和操作数,其中操作数分为:
- 立即数即常数,如$8;
- 寄存器数,表示某个寄存器中保存的值,如%eax;而对字节操作而言,是8个单字节寄存器中的一个,如%al;
- 存储器引用,根据计算出的有效地址来访问存储器的某个位置。
汇编指令:
- 寄存器寻址
movl %eax, %edx
- 立即寻址
movl $0x123, %edx
- 直接寻址
movl 0x123, %edx
- 变址寻址
movl 4(%ebx), %edx
- 进栈
pushl %eax
- 出栈
popl %eax
- 函数调用
call 0x12345
- 函数返回
ret
- 建立函数堆栈enter
push1 %ebp
movl %esp, %ebp
- 撤销函数堆栈leave
movl %ebp, %esp
popl %ebp
反汇编 C 程序
1.创建.c文件
$ vim main.c
2.编译main.c并运行
$ gcc main.c -o main
$ ./main
$ echo $?
3.将main.c编译成汇编代码
$ gcc –S –o main.s main.c -m32
main.s文件:
.file "main.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
endbr32
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
movl 8(%ebp), %eax
addl $3, %eax
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
endbr32
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
pushl 8(%ebp)
call g
addl $4, %esp
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size f, .-f
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
endbr32
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
pushl $8
call f
addl $4, %esp
addl $1, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
.globl __x86.get_pc_thunk.ax
.hidden __x86.get_pc_thunk.ax
.type __x86.get_pc_thunk.ax, @function
__x86.get_pc_thunk.ax:
.LFB3:
.cfi_startproc
movl (%esp), %eax
ret
.cfi_endproc
.LFE3:
.ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 4
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 4
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 4
4:
分析汇编代码
main.s中以.开头是都是用于链接的辅助信息,在实际过程中不被执行,删除他们得到纯汇编代码
g:
pushl %ebp
movl %esp, %ebp
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
movl 8(%ebp), %eax
addl $3, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
pushl 8(%ebp)
call g
addl $4, %esp
leave
ret
main:
pushl %ebp
movl %esp, %ebp
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
pushl $8
call f
addl $4, %esp
addl $1, %eax
leave
ret
寄存器:
- eip:指向指令
- ebp:指向堆栈栈底
- esp:指向堆栈栈顶
- eax:暂存数值
遇到的问题
直接复制实验楼的命令粘到虚拟机中,会提示错误:“没有那个文件或目录”,手动输入命令后错误消失