0%

汇编学习

1711196825096

常用的gdb调试指令

gdb指令 含义 实例
break *adress或b *address 在地址adress处设置断点。 break *0x7c00``b *0x7c00
break symbol或b symbol 在符号symbol处设置断点,例如symbol一般是函数名。 break setup_kernel``b setup_kernel
break filename:line_number 在文件filename处的第line_numer行设置断点 b mbr.asm:12
add-symbol-file filename address 加载符号表filename到地址address处 add-symbol-file mbr.symbol 0x7c00
x/FMT address address是内存地址,FMT格式是重复的单元个数+格式+大小。
重复的单元个数是一个数字,表示我们希望查看多少个单元。正数表示从address向后查看。负数表示从address向前查看。格式是一个字符,可以是o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char), s(string)。``大小是一个字符,可以是b(byte, 1 byte), h(halfword, 2 byte), w(word, 4 byte), g(giant, 8 bytes)。
x/5xw 0x8032``x/10i 0x7c00
continue或c 继续执行正在调试的程序到断点处暂停。
step或s 执行一条C语句,如果遇到函数调用语句,则会进入函数体中。
next或n 执行一条C语句,函数调用语句不会进入函数体,把函数当成一条语句执行。
stepi或si 执行一条汇编语句,如果遇到函数调用语句,则会进入函数体中。
nexti或ni 执行一条汇编语句,函数调用语句不会进入函数体,把函数当成一条语句执行。
info registers 查看所有寄存器的值
layout layout_name layout_name包含src,asm,split,regs。``src显示源代码窗口和命令窗口,asm显示汇编代码窗口和命令窗口,split显示源代码窗口、汇编代码窗口和命令窗口,regs显示寄存器窗口。 layout split
focus layout_window 转换当前窗口到layout窗口,layout_window包含src,asm,regs,cmd。任何时刻gdb的当前窗口只有一个,并且使用方向键的效果只会在当前窗口处显示。 focus cmd
file symbol_file 加载符号表,为gdb提供debug信息。 file ../build/kernel.o
set disassembly-flavor intel 设置汇编代码格式为intel风格
set architecture name 设置指令对应的CPU架构,name包含i8086(16位),i386(32位) set architecture i386

详解子程序调用过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
asm_switch_thread:
push ebp
push ebx
push edi
push esi

mov eax, [esp + 5 * 4]
mov [eax], esp ; 保存当前栈指针到PCB中,以便日后恢复

mov eax, [esp + 6 * 4]
mov esp, [eax] ; 此时栈已经从cur栈切换到next栈

pop esi
pop edi
pop ebx
pop ebp

sti
ret

1.push指令

push %eax

将eax数值压入栈中,可分解为:

sub $4, %esp ——> esp = esp - 4

mov %eax, (%esp) ——> *(int32_t *)esp = eax

2.pop指令

pop %eax

将eax数值弹出栈,可分解为:

mov (%esp), %eax ——> eax = *(int32_t *)esp

add $4, %esp ——> esp = esp + 4

3.call指令

call 0x12345

调用0x12345这个地址,可分解为:

push %eip ——> 将cpu下一条要执行的指令压入栈中

mov $0x12345, %eip ——> eip = 0x12345

注意:CPU下一条指令将会从地址0x12345中取。

4.ret指令

ret

返回call之前的地址,可分解为:

pop %eip ——> 将call压入栈的指令弹出赋给eip