linux内核分析,源码分析 - 中国科学技术大学软件学院MOOC 笔记1

166 阅读1分钟

linux内核分析,源码分析 - 中国科学技术大学软件学院MOOC学习梳理得到的笔记

x86寄存器

image.png

image.png

指令前置知识

前置知识: 指令的结尾字母表示当前是多少位系统

  • b 后缀,表示为 8bit
  • w 后缀,表示为 16bit
  • l 后缀,表示为 32bit
  • q 后缀,表示为 64bit

例如:MOV 指令根据系统位数不同,分别有 movb、movw、movl、movq


MOV 指令

  1. register mode (寄存器寻址)
movl %eax, %edx

表示将 eax 寄存器里的内容放到 edx 里; 相等于 edx = eax;

  1. immediate (立即寻址)
movl $0x123, %edx

将数值 0x123 放到寄存器 edx 里; 相当于 edx = 0x123;

  1. direct (直接寻址)
movl 0x123, %edx

将内存地址为0x123位置的内存数据放到寄存器 edx 里; 相当于 edx = *(int32_t *)0x123;

  1. indirect (间接寻址)
movl (%ebx), %edx

将寄存器ebx里的值指向的内存地址,内存中所包含的数据放到寄存器 edx 里; 相当于 edx = *(int32_t *)ebx;

  1. displaced (变址寻址)
movl 4(%ebx), %edx

将寄存器ebx里的值指向的内存地址 +4 所指向的内存中的数据,放到 寄存器 edx 里; 相当于 edx = *(int32_t *)(ebx + 4); 这里的 4 为 4byte 相当于 32bit

备注:

  • 以 % 开头的寄存器标识符
  • 立即数是以 $ 开头的数值
  • 直接寻址:直接访问一个指定的内存地址的数据
  • 间接寻址:将寄存器的值作为一个内存地址来访问内存
  • 变址寻址:在间接寻址之时改变寄存器的数值

PUSH 指令

pushl %eax

将eax里的内容推到栈顶内存中

相当于

subl $4,%esp
movl %eax,(%esp)
  • 堆栈是向下增长的
  • esp 是堆栈寄存器,存放指向栈顶的内存地址

POP 指令

popl %eax

相当于

movl (%esp),%eax
addl $4,%esp

将堆栈的栈顶的数据弹出(出栈),放到eax中

CALL 和 RET

call 0x10A00C

相当于

pushl %eip
movel $0x10A00C,%eip

ret

相当于

popl %eip

注意:eip不能被程序员直接使用,必须使用相关指令间接使用(例如使用 call指令).

enter 和 leave 指令

enter

相当于

push %ebp
movel %esp,%ebp

leave

相当于

movel %ebp,%esp
popl %ebp

c 编译成 汇编

gcc -S -o main32.s x86.c -m32

image.png

// gcc -S -o main32.s x86.c -m32
int g(int x) { return x + 3; }

int f(int x) { return g(x); }

int main(void) { return f(8) + 1; }
_g:                                     ## @g
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	movl	8(%ebp), %eax
	addl	$3, %eax
	popl	%ebp
	retl
_f:                                     ## @f
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	movl	8(%ebp), %eax
	movl	%eax, (%esp)
	calll	_g
	addl	$8, %esp
	popl	%ebp
	retl
_main:                                  ## @main
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	$0, -4(%ebp)
	movl	$8, (%esp)
	calll	_f
	addl	$1, %eax
	addl	$8, %esp
	popl	%ebp
	retl