gpt4 book ai didi

c - 理解 C 反汇编调用

转载 作者:太空狗 更新时间:2023-10-29 17:16:08 27 4
gpt4 key购买 nike

我想了解 C 调用约定。为此,我编写了以下代码:

#include <stdio.h>
#include <stdlib.h>

struct tstStruct
{
void *sp;
int k;
};

void my_func(struct tstStruct*);

typedef struct tstStruct strc;

int main()
{
char a;
a = 'b';
strc* t1 = (strc*) malloc(sizeof(strc));
t1 -> sp = &a;
t1 -> k = 40;
my_func(t1);
return 0;
}

void my_func(strc* s1)
{
void* n = s1 -> sp + 121;
int d = s1 -> k + 323;
}

然后我通过以下命令使用 GCC:

gcc -S test3.c

并想出了它的 assembly 体。我不会展示我得到的全部代码,而是粘贴函数 my_func 的代码。是这样的:

my_func:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -24(%rbp)
movq -24(%rbp), %rax
movq (%rax), %rax
addq $121, %rax
movq %rax, -16(%rbp)
movq -24(%rbp), %rax
movl 8(%rax), %eax
addl $323, %eax
movl %eax, -4(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc

据我了解,情况是这样的:首先,调用者的基指针被压入堆栈,其堆栈指针成为新的基指针,为新函数设置堆栈。但其余的我不明白。据我所知,参数(或指向参数的指针)存储在堆栈中。如果是这样,第二条指令的目的是什么,

movq        -24(%rbp), %rax

在这里,%rax 寄存器的内容被移动到距离寄存器 %rbp 中的地址 24 字节的地址。但是 %rax 中是什么????最初什么都没有存储在那里???我想我很困惑。请帮助了解此功能的工作原理。 提前致谢!

最佳答案

您混淆了 AT&T 语法和 Intel 语法。

movq -24(%rbp), %rax

在 Intel 语法中是

mov rax,[rbp-24]

因此它将由 rbp 寻址的数据移动到 rax,而不是相反。操作数的顺序在 AT&T 语法中是 src, dest,而在 Intel 语法中是 dest, src。

然后,为了摆脱 GAS 指令以使反汇编更易于阅读,我使用 gcc 简单地使用 gcc test3.c 组装了代码,并使用 ndisasm -b 64 a 对其进行了反汇编.out。请注意,下面由 NDISASM 生成的 my_func 函数的反汇编采用 Intel 语法:

000005EF  55                push rbp000005F0  4889E5            mov rbp,rsp        ; create the stack frame.000005F3  48897DE8          mov [rbp-0x18],rdi ; s1 into a local variable.000005F7  488B45E8          mov rax,[rbp-0x18] ; rax = s1 (it's a pointer)000005FB  488B00            mov rax,[rax]      ; dereference rax, store into rax.000005FE  4883C079          add rax,byte +0x79 ; rax = rax + 12100000602  488945F8          mov [rbp-0x8],rax  ; void* n = s1 -> sp + 12100000606  488B45E8          mov rax,[rbp-0x18] ; rax = pointer to s10000060A  8B4008            mov eax,[rax+0x8]  ; dereference rax+8, store into eax.0000060D  0543010000        add eax,0x143      ; eax = eax + 32300000612  8945F4            mov [rbp-0xc],eax  ; int d = s1 -> k + 32300000615  5D                pop rbp00000616  C3                ret

有关 Linux x86-64 调用约定 (System V ABI) 的信息,请参阅 What are the calling conventions for UNIX & Linux system calls on x86-64 的答案。 .

关于c - 理解 C 反汇编调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16088946/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com