汇编及C/C++汇编调用约定讲解
> 汇编及C/C++汇编调用约定(汇总帖)
> 汇编编译和gdb调试命令列表
> gdb TUI使用方法
> 汇编C语言调用约定(标准函数)
> 汇编C语言调用约定(递归函数)
> C++内存模型以及寄存器指针rsp和rbp
1. 汇编编译命令
as exit.s -o exit.o
编译指令:exit.s is source file and exit.o is target fileld exit.o -o exit
链接指令:ld 链接器命令# something
注释echo $?
获取上次程序上次输出结果, 这个值保存在%ebx中- 在64位机器上编译链接32位汇编代码,as 加参数
--32
,ld 加参数-m elf_i386
- 对于错误提示:
invalid instruction suffix for push
,在64位系统和32位系统的as命令对于某些汇编指令的处理支持不一样,在代码头部添加.code32即可 - 使用gdb调试时需要给as加上
--gstabs
参数
2. gdb 调试常用命令(文末含有附录)
print/f $reg
打印$reg
寄存器的内容
[!!] 或者打印变量的值print/f ucharMax
格式 f 可以为:
x — 十六进制
d — 有符号十进制
u — 无符号十进制
o — 八进制
t — 二进制
a — 地址
c — 字符
f — 浮点x/rsf addr
打印内存地址addr的内容- r重复计数:默认值为1
- s大小:默认值为字
b — 字节
h — 半字
w — 字
g — 双字 - f格式:与print中的/f一样,多了:
s — 字符串
i — 指令
3. 关于上述参数s
- 32位机器一个字(即word)为32bit(8Byte),双字(g)64bit,半字(h)16bit,字节(b)8bit
- 例如
x/16bx $esp 打印出的形式为
0x7ffffe4d8: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7ffffe4e0: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
把一个Byte按十六进制打印,就是俩位
4. disassemble
- /m 将源码和汇编一起排列
- /r 查看16进制代码
5. 关于大小端
/*
* (gdb) print/x &charMax
* $4 = 0x61fe1e
* (gdb) x/bx 0x61fe1e
* 0x61fe1e: 0x7f
*
* (gdb) x/bx 0x61fe1f
* 0x61fe1f: 0xff
*
* (gdb) x/hx 0x61fe1e
* 0x61fe1e: 0xff7f [!!] 小端模式,高字节地址内容在高位,低字节地址内容在低位
*
* (gdb) x/2bx 0x61fe1e
* 0x61fe1e: 0x7f 0xff [!!] 这样输出的是无视大小端模式的
*/
附录:gdb 调试命令
- l :(字母l)列出源码
- b n :在第n行处设置断点
- b func:在函数func()的入口处设置断点
- 条件断点:条件可以是任何合法的c 表达式。 例如 b n if val1 == val2
- 当已经设置了断点,可以用condition 命令对断点号添加条件, 例: condition 2 val1 == val2 , 注意,没有if 单词
- 当对变量的改变更感兴趣时,可以用watch 命令
- info break: 查看断点信息
- r:运行程序
- n:单步执行
- s:单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的
- c:继续运行
- p 变量 :打印变量的值 也能够修改变量的值(用 = 赋值) // 打印寄存器值。 p $eax
- bt:查看函数堆栈
- finish:退出函数
- display 每次中断或单步都显示你关心的变量
- undisplay <编号>
- shell 命令行:执行shell命令行
- set args 参数:指定运行时的参数
- show args:查看设置好的参数
- info program: 来查看程序的是否在运行,进程号,被暂停的原因。 // 打印寄存器数组, info reg, 简写 i reg
- clear 行号n:清除第n行的断点
- delete 断点号n:删除第n个断点
- disable 断点号n:暂停第n个断点
- enable 断点号n:开启第n个断点