铿锵: compiling with non-flat x86 stack model

标签 c x86 llvm-clang

如果我理解 clang 假设 x86 的堆栈段是平坦的(有 0 基数)。例如,使用以下命令行进行编译时:

clang -cc1 -S -mllvm --x86-asm-syntax=intel -o - -triple i986-unknown-unknown -mrelocation-model static xxx.c

xxx.c:

void f()
{
    int a = 5;
    int *ap = &a;
    int b = *ap;
}

生成以下组件:

f:
    sub     ESP, 12
    lea     EAX, DWORD PTR [ESP + 8]
    mov     DWORD PTR [ESP + 8], 5
    mov     DWORD PTR [ESP + 4], EAX
    mov     EAX, DWORD PTR [ESP + 4]
    mov     EAX, DWORD PTR [EAX]
    mov     DWORD PTR [ESP], EAX
    add     ESP, 12
    ret

只有当堆栈平坦时,这才可能是正确的,因为 EAX 包含相对于 SS 基址的偏移量。

是否可以使用任意基数编译 SS 的 C 代码?

最佳答案

在保护模式下执行时,段寄存器不包含可以使用的偏移量。相反,每个部分都是独立于其他部分的。据我所知,目前使用的操作系统都没有使用 ABI,其中指针包含段信息,并且您可以获取任何局部变量(放置在堆栈上)的地址,这是必要的。我不认为 clang(或 gcc)可以为这样的模型编译代码。

关于铿锵: compiling with non-flat x86 stack model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28010142/

相关文章:

c++ - C 优化 - 低级代码

在linux for windows上交叉编译不会输出DLL文件

objective-c - 在 Objective - C 中乘以预处理器常量

python - 没有使用 Python/C API 的名为 ctypes 的模块

c++ - 编译麻烦c转c++反

c - 如何找出 valgrind 报告中出现 "Invalid Free()"错误的原因

c - 使用 32 位 block 对 1024 位 2 的补码进行有符号乘法

gcc - ASM x86 相对 JMP

c++ - gcc x86 Windows 堆栈对齐

C:如果已经定义,则忽略函数的第二个定义