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:暂存数值

遇到的问题

直接复制实验楼的命令粘到虚拟机中,会提示错误:“没有那个文件或目录”,手动输入命令后错误消失

posted @ 2020-10-18 11:04  20209318赵姝  阅读(114)  评论(1编辑  收藏  举报