x86汇编代码功能、栈地址范围分析及C等效代码验证问询
x86汇编代码功能、栈地址范围分析及C等效代码验证问询
一、先搞懂这段汇编到底在干嘛
这段x86-64汇编是在做深度优先搜索(DFS)——遍历一个树形结构的节点,查找是否存在数据值为17的节点。具体细节:
- 数据段里的每个节点都是固定格式:开头4字节(
.long)是节点的数值,后面跟着一串8字节指针(.quad)指向它的子节点,最后用0(空指针)收尾,表示子节点列表结束。比如节点A的数值是3,子节点是B、C、D;节点B数值是10,子节点是E、F,以此类推。 - 入口
_start里,把要找的17放到%esi,根节点A的地址放到%rdi,然后调用func函数。最后根据func的返回值设置程序退出码:找到17返回1,退出码为1-1=0;没找到返回0,退出码为1-0=1。
二、执行路径和最终结果
咱们跟着代码走一遍执行流程:
从根节点A开始,先检查A的数值是3,不是17,于是遍历它的子节点:
- 第一个子节点是B,进入B的检查:B的数值是10,不是17,继续遍历B的子节点。
- B的第一个子节点是E,E的数值是85,不是17,且E没有子节点,返回0。
- 回到B,遍历下一个子节点F,F的数值是2,不是17,也没子节点,返回0。B的子节点遍历完,返回0给A。
- 回到A,遍历下一个子节点C,C的数值是22,不是17,没子节点,返回0。
- 回到A,遍历最后一个子节点D,D的数值正好是17!匹配成功,返回1。
最终func返回1,程序退出码为0。
三、%rsp的地址范围计算
假设初始时栈指针%rsp的值是X(x86的栈是向下增长的,地址越用越小),咱们算一下栈能用到的最低地址:
每次调用func的时候,都会先push %rbp(占8字节);在递归调用子节点之前,还要push %rdi和push %r10(各8字节,加起来16字节)。
栈最深的时刻是走到A→B→F这条路径的时候:
- 初始
%rsp = X - 调用
func(A):push rbp →%rsp = X-8 - 准备调用
func(B):push rdi(A的地址)→X-16;push r10(0)→X-24;然后调用func(B) - 调用
func(B):push rbp →X-32 - 准备调用
func(F)(E返回后,遍历B的下一个子节点):push rdi(B的地址)→X-40;push r10(1)→X-48;然后调用func(F) - 调用
func(F):push rbp →X-56
这就是栈的最低地址,之后栈会通过pop操作逐步回收空间。所以%rsp的范围是从X(初始值)到X-56,也就是[X-56, X](栈地址递减,实际使用的地址是X、X-8、X-16…直到X-56)。
四、你的C代码需要修正
你写的C代码只遍历了当前节点的直接子节点,没有递归进入子节点的子节点,这和原汇编的DFS逻辑不符。正确的代码应该模拟递归搜索:
首先定义对应汇编的节点结构:
typedef struct Node { long data; // 对应汇编里的.long字段 struct Node* sons[];// 柔性数组,存储子节点指针,最后用NULL结尾 } Node;
然后实现func函数,完全复刻汇编的逻辑:
int func(Node* root, int X) { // 先检查当前节点是不是目标值 if (root->data == X) { return 1; } // 遍历所有子节点,递归搜索每个子节点 int i = 0; while (root->sons[i] != NULL) { // 如果子节点的递归搜索找到了目标,直接返回1 if (func(root->sons[i], X)) { return 1; } i++; } // 所有子节点都搜过了,没找到目标 return 0; }
最后是模拟汇编_start的主逻辑:
#include <stdlib.h> // 上面的Node定义和func函数 int main() { // 静态初始化所有节点,对应汇编数据段的内容 Node G = {8, {NULL}}; Node F = {2, {NULL}}; Node E = {85, {NULL}}; Node D = {17, {&G, NULL}}; Node C = {22, {NULL}}; Node B = {10, {&E, &F, NULL}}; Node A = {3, {&B, &C, &D, NULL}}; int result = func(&A, 17); // 对应汇编里的退出码计算:1 - result exit(1 - result); }
这个代码和汇编逻辑完全一致:递归遍历每个节点的所有子节点,只要找到匹配值就立刻返回,否则遍历完所有节点后返回0。
备注:内容来源于stack exchange,提问作者SpaceNugget
相关产品推荐
相关产品推荐

