(学习笔记)3.10 在机器级程序中将控制和数据结合起来(3.10.1 理解指针3.10.2 应用:使用GDB调试器)

张开发
2026/4/12 14:49:34 15 分钟阅读

分享文章

(学习笔记)3.10 在机器级程序中将控制和数据结合起来(3.10.1 理解指针3.10.2 应用:使用GDB调试器)
文章目录线索栏笔记栏1. 指针的六项关键原则2. 函数指针1概念2声明与使用示例3阅读复杂声明的技巧3. GDB核心价值4. GDB基本使用流程1启动2设置断点3运行与单步4检查状态5停止5. GDB常用命令分类 (图3-39摘要)1开始/停止2断点管理3执行控制4检查代码5检查数据6获取信息总结栏线索栏本节为何将“控制”与“数据”结合起来讨论关于指针需要理解的六个关键原则是什么类型、值、创建、引用、与数组关系、类型转换如何声明一个函数指针阅读复杂声明如 int (f)(int)的关键技巧是什么GDB调试器在机器级程序分析中的核心价值是什么使用GDB调试程序通常包含哪几个基本步骤其命令主要分为哪几类功能笔记栏指针是C语言的核心特色提供了一种统一引用不同数据结构元素的方式。1. 指针的六项关键原则1每个指针都有类型类型 T表明指向的是 T类型的对象。void是通用指针。指针类型是C语言的抽象用于帮助避免寻址错误不直接体现在机器代码中。2每个指针都有一个值即某个对象的地址。NULL(0)值表示指针不指向任何地方。3指针用 运算符创建可应用于任何左值lvalue。在机器级运算符常用 leaq指令计算有效地址实现。4*操作符用于间接引用指针结果是一个值类型与指针所指类型一致。在机器级通过 mov等内存访问指令实现。5数组与指针紧密联系①数组名可像不可修改的指针一样引用。②数组引用 a[i]等价于指针运算和间接引用 *(ai)。③指针运算 pi的地址计算为 p L·i其中 L是指针指向数据类型的大小。这体现了指针运算的“自动缩放”。6将指针从一种类型强制转换为另一种类型只改变其类型不改变其值。但会影响后续指针运算的缩放因子。强制类型转换的优先级高于加法。2. 函数指针1概念指针可以指向函数的机器代码中第一条指令的地址。2声明与使用示例intfun(intx,int*p);// 函数原型int(*fp)(int,int*);// 声明函数指针fpfpfun;// 将fp指向funinty1;intresultfp(3,y);// 通过指针调用函数3阅读复杂声明的技巧从标识符开始由内向外阅读。1例如 int (* f)(int *)( * f)表示 f是一个指针( * f) (int * )表示 f是一个指向函数的指针该函数以 int *为参数最后该函数返回 int。2* f两边的括号是必需的否则 int * f(int*)会被解读为“返回 int*的函数 f”。GDBGNU调试器支持对机器级程序进行运行时评估和动态分析是研究程序行为、连接源代码与机器状态的关键工具。3. GDB核心价值通过设置断点、单步执行、检查寄存器/内存可以动态观察并控制程序的执行弥补了仅通过静态阅读代码进行推断的不足。4. GDB基本使用流程1启动gdb prog2设置断点在函数入口break function_name或指定地址break *address。3运行与单步1run运行程序。2遇到断点后使用 stepi(单条指令)/nexti(以函数调用为单位)/continue(继续) 控制执行。4检查状态使用 disas反汇编print或 x检查寄存器和内存内容info查看帧和寄存器信息。5停止kill停止程序quit退出GDB。5. GDB常用命令分类 (图3-39摘要)1开始/停止run, kill, quit2断点管理break, delete3执行控制stepi, nexti, continue, finish4检查代码disas反汇编函数或地址范围 print /x $rip查看PC5检查数据print $rax输出寄存器值可格式化/x十六/t二print *(long *) 0xADDRESS输出指定地址的值x/20b multstore检查函数起始的20个字节6获取信息info registers, info frame, help注可以使用DDD图形化前端来改善GDB的命令行体验。总结栏本节将程序的两个核心要素——“控制流”与“数据操作”——结合并引入了分析和验证它们交互的关键工具。指针是统一的“引用”抽象指针的六项原则深刻揭示了C语言操作数据的统一模型。无论数据是简单变量、数组、结构体还是函数都可以通过“地址类型”这一对信息来定位和解释。理解指针运算的“自动缩放”和强制类型转换的语义是读懂任何复杂数据访问代码的基础。函数指针是“可传递的控制流”它将代码也视为一种数据其地址可以被存储、传递和动态调用。这极大地增加了程序的灵活性是实现回调、动态加载、面向对象多态等机制的底层支撑。GDB是连接静态与动态的桥梁仅仅阅读汇编代码是静态的推理。GDB允许我们动态地、交互式地验证推理观察程序在真实硬件上的精确状态变化寄存器、内存、PC。掌握GDB或DDD是将机器级知识转化为实际调试和分析能力的关键步骤。实践导向本节内容特别是GDB具有极强的实践性。后续学习缓冲区溢出、栈随机化等安全议题以及分析复杂程序行为都将直接依赖于本节介绍的指针知识和GDB调试技能。

更多文章