论坛首页 安全工具分享区 阅读主题

[原创]从GDB中观察x86-64数组、指针、结构体在汇编中的表示

169 浏览 0 回复
#1 楼主 2026-06-01 21:08:47
测试代码#include <stdio.h>
#include <string.h>

struct Student {
    int id;
    int score;
    char name[16];

void process_array() {
    int sum = 0;
    for (int i = 0; i < 5; i++) {
        sum += arr[i];
    printf("sum = %d\n", sum);

void process_pointer() {
    int x = 42;
    int *p = &x;
    *p = 100;
    printf("x = %d\n", x);

void process_struct() {
    struct Student s;
    s.id = 1;
    s.score = 95;
    strcpy(s.name, "Alice");
    printf("id=%d score=%d name=%s\n", s.id, s.score, s.name);

int main() {
    process_array();
    process_pointer();
    process_struct();
    printf("%d\n",sizeof (struct Student));
    return 0;
}运行环境:
    Ubuntu 20.04.6 LTS编译指令:
    gcc -g -O0 -o main main.cgcc版本    gcc version 9.4.0调试工具:    GDB
开始执行进入main 函数:=> 0x5555555552d0 <main>: endbr64       0x5555555552d4 <main+4>: push   %rbp      0x5555555552d5 <main+5>: mov    %rsp,%rbp      0x5555555552d8 <main+8>: mov    $0x0,%eax      0x5555555552dd <main+13>: callq  0x555555555169 <process_array>
   传入了一个0到process_array函数内部,但是他没用容rdi去传参,那process_array函数参数可能是一个不定数量的参数进入process_array函数内部:这段代码中构建了栈帧,存入了金丝雀的值   0x55555555516d <process_array+4>: push   %rbp   0x55555555516e <process_array+5>: mov    %rsp,%rbp   0x555555555171 <process_array+8>: sub    $0x30,%rsp   0x555555555175 <process_array+12>: mov    %fs:0x28,%rax   0x55555555517e <process_array+21>: mov    %rax,-0x8(%rbp)
然后清零了eax: 可是eax不是传入的不定长参数浮点数的数量么?不确定 再看看 0x555555555182 <process_array+25>: xor    %eax,%eax
继续执行:这段代码在一个连续的区域初始化了一些值:可能是一个数组,=> 0x555555555184 <process_array+27>: movl   $0xa,-0x20(%rbp)      0x55555555518b <process_array+34>: movl   $0x14,-0x1c(%rbp)      0x555555555192 <process_array+41>: movl   $0x1e,-0x18(%rbp)      0x555555555199 <process_array+48>: movl   $0x28,-0x14(%rbp)      0x5555555551a0 <process_array+55>: movl   $0x32,-0x10(%rbp)
      查看内存,验证内容      (gdb) x/10x $rbp-0x20      0x7fffffffdcf0: 0x0000000a 0x00000014 0x0000001e 0x00000028      0x7fffffffdd00: 0x00000032 继续执行:看起来是设置了两个变量值为0=> 0x5555555551a7 <process_array+62>: movl   $0x0,-0x28(%rbp)      0x5555555551ae <process_array+69>: movl   $0x0,-0x24(%rbp)
继续执行:=> 0x5555555551b5 <process_array+76>: jmp    0x5555555551c7 <process_array+94>      0x5555555551b7 <process_array+78>: mov    -0x24(%rbp),%eax      0x5555555551ba <process_array+81>: cltq         0x5555555551bc <process_array+83>: mov    -0x20(%rbp,%rax,4),%eax      0x5555555551c0 <process_array+87>: add    %eax,-0x28(%rbp)      0x5555555551c3 <process_array+90>: addl   $0x1,-0x24(%rbp)      0x5555555551c7 <process_array+94>: cmpl   $0x4,-0x24(%rbp)      0x5555555551cb <process_array+98>: jle    0x5555555551b7 <process_array+78>      0x5555555551cd <process_array+100>: mov    -0x28(%rbp),%eax
发现一个循环:跳转去0x5555555551c7位置执行代码: 使用了 rbp-0x24中的值和0x4进行比较,判断 rbp-0x24是否小于等于4如果小于进入循环体 先将rbp-4放在了eax中, ovl   $0x0,-0x24(%rbp) 然后可能进行了强制类型转换从4字节升到了8字节,观察后面代码发现,是为了和rbp进行计算,那也就是eax是数组的下标 rbp-4就是循环中的累加参数。 mov    -0x20(%rbp,%rax,4

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291299.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号