【问题标题】:x86 mov instruction in C pointer of different size不同大小的C指针中的x86 mov指令
【发布时间】:2017-05-04 03:48:12
【问题描述】:

我正在尝试在 C 中复制 x86 mov 指令,例如 mov %ecx,-0x4(%ebp) 并且对如何执行感到困惑。我有一个用于寄存器的 int 数组和一个 int 位移。如何将 %ecx 的值移动到比 %ebp 中存储的值小 4 的内存地址?

我有:

int* destAddress=(int*)(displacement + registers[destination]);
*destAddress=registers[source];

我收到警告:从不同大小的整数转换为指针。

【问题讨论】:

  • 你怎么知道destAddress 是一个有效的地址?假设displacement-4registers[destination] 是某个地址。你怎么知道这个结果地址是被分配的,而不是随机的?
  • 要回答您的问题,您将int 转换为int*,这似乎是一个问题(当然是未定义的行为)。如果你在 X86_64 上,你应该考虑为displacement 输入size_t 和为registers 输入unsigned long long
  • 我不确定我是否理解代码示例或您想要做什么...?结果应该存储在哪里?初始值是多少?你想做什么:registers[destination] = registers[source] + displacement?指针有什么用?它应该指向什么?

标签: c assembly x86


【解决方案1】:
mov %ecx,-0x4(%ebp)

或者,在英特尔语法中:

mov DWORD PTR [ebp-4], ecx

正在将ECX 中的值存储到内存位置[ebp-4]

EBP 是“基指针”,通常用于(在未优化的代码中)访问堆栈上的数据。根据负偏移量,这条指令几乎可以肯定将ECX 的值存储到第一个 DWORD 大小的局部变量中。

如果你想把它翻译成 C,那就是:

int local = value;

假设value映射到ECX寄存器,而local是分配在栈上的局部变量。真的,就是这样。

[除了 C 编译器通常会将这样的局部变量放在寄存器中,因此这实际上会转换为更像 mov edx, ecx 的东西。它会溢出到堆栈的唯一一次是它用完了寄存器(这在寄存器非常少的 x86 ISA 中并不少见)。

或者,您可以通过创建变量来强制它溢出volatile: volatile int local = value;.
但在实际代码中没有充分的理由这样做。]

当然,正如您在汇编语言指令中看到的那样,这里有指针取消引用,但它不会在 C 表示中体现出来。

如果您想在其中获得一些指针表示法,假设您在堆栈上分配了一个 array 值,并且想要初始化它的第一个成员:

int array[4];
array[0] = value;   // set first element of array to 'value' (== ECX)

位移 (-4) 根本不会出现在 C 代码中。 C 编译器会处理这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    相关资源
    最近更新 更多