gpt4 book ai didi

c - 通过 EBP 从调用函数获取本地变量

转载 作者:太空宇宙 更新时间:2023-11-04 02:52:26 26 4
gpt4 key购买 nike

我正在尝试通过 EBP 从被调用方获取调用方中定义的局部变量。这应该是可能的,但如果不是,请解释原因。

这是我现在的代码:

#include <stdio.h>

void TEST(int a, int b, int c){
int answer;
printf("a: %d | b: %d | c: %d\n", a, b, c);

__asm__ __volatile__(
".intel_syntax;"
"mov %0, dword ptr ds:[ebp + 20];" <-- EBP+20 == d == 42
".att_syntax;"
: "=r" (answer)
:
:
);

printf("Answer: %d\n", answer);
}

int main(void){
int a = 13;
int b = 14;
int c = 15;
int d = 42;
TEST(a, b, c);
}

TEST 被调用时,我希望堆栈看起来像下面这样:

|+20|  | 13     <-- d
|+16| | 14 <-- c
|+12| | 15 <-- b
|+ 8| | 42 <-- a
|+ 4| | return address
| 0| | EBP
|- 4| | local var answer
|- 8| | ...

如果我尝试编译以下代码,我会得到:

test.c: Assembler messages:
test.c:7: Error: segment register name expected

哪里出错了?

最佳答案

move mem2,mem1

是不允许的。但这将由 gcc 处理,即使在 intel 语法上也是如此。我的假设是不正确的。 Gcc 将为 intelat&t 语法生成正确的代码。

 "movl  mem1,%0"
: "=r" (mem2)

Gcc 会为我们生成有效的代码:

mov    mem1,%eax
mov %eax,mem2

错误:需要段寄存器名称:

gcc 无法获取段寄存器名称。但是有段ds 寄存器。而且即使不提及段寄存器也应该没问题。实际问题只是前缀问题

应该做的:要解决这个问题,我们必须使用 nonprefix或者加上前缀 %

同样的例子:

它在 x64 机器上。你应该改变 rbp->ebp。并且0x10也可以改变

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void TEST(int a, int b, int c) {
int answer;

int x = 16;


__asm__ __volatile__(
".intel_syntax noprefix ;"
"mov %0, dword ptr ds:[rbp + %1+0];"
".att_syntax;"
: "=r" (answer)
: "r"((uintptr_t)x) /* x is input operand */
);
printf("Answer: %d\n", answer);
__asm__ __volatile__(
" movl 0(%%rbp,%1,1),%0"
: "=r" (answer)
: "r"((uintptr_t)x) /* x is input operand */
);
printf("Answer: %d\n", answer);
__asm__ __volatile__(
"movl 0x10(%%rbp),%0"
: "=r" (answer)
);
printf("Answer: %d\n", answer);
__asm__ __volatile__(
".intel_syntax;"
"mov %0, dword ptr [%%rbp + 0x10];"
".att_syntax;"
: "=r" (answer)
);
printf("Answer: %d\n", answer);

//the same as you wrote, just I added noprefix
__asm__ __volatile__(
".intel_syntax noprefix ;"
"mov %0, dword ptr ds:[rbp + 0x10];"
".att_syntax;"
: "=r" (answer)
);
printf("Answer: %d\n", answer);
//this lines just to test if we refer the same address as address of d
void *addressd;
__asm__ __volatile__(
"lea 0x10(%%rbp),%0"
: "=r" (addressd)
);
printf("TEST: address of d %p\n", addressd);
}

int main(void) {
int a = 13;
int b = 14;
int c = 15;
int d = 42;
TEST(a, b, c);
printf("address of d %p", &d);
}

关于c - 通过 EBP 从调用函数获取本地变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20773028/

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