测试代码#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
[原创]从GDB中观察x86-64数组、指针、结构体在汇编中的表示
169 浏览
0 回复
暂无回复,快来抢沙发吧!