gpt4 book ai didi

c - x86 add 和 addl 操作数相加错误?

转载 作者:行者123 更新时间:2023-11-30 19:13:06 27 4
gpt4 key购买 nike

我使用 xv6,它在 x86 机器上实现了原始的 UNIX。我在 C 程序中编写了非常简单的内联汇编:

register int ecx asm ("%ecx");
printf(1, "%d\n", ecx);
__asm__("movl 16(%esp), %ecx\t\n");
printf(1, "%d\n", ecx);
__asm__("add $0, %ecx\t\n");
printf(1, "%d\n", ecx);
__asm__("movl %ecx, 16(%esp)\t\n");

我通常会得到第二个 print 语句打印的类似 434 的值。但是,在 add 命令之后它会打印 2。如果我使用 addl 命令,它也会打印 2。我使用的是 xv6 的最新稳定版本。所以,我真的不怀疑这是问题所在。还有其他方法可以在内联汇编中添加两个数字吗?

本质上我需要将 16(%esp) 增加 4。

<小时/>

将代码编辑为:

__asm__("addl $8, 16(%esp)\t\n");

最佳答案

1) 在您的示例中,您没有将 ecx 增加 4,而是将其增加 0。

__asm__("addl $4, %ecx");

2) 您应该能够将多个命令链接到一个 asm 调用中

__asm__("movl 16(%esp), %ecx\n\t"
"addl $4, %ecx\n\t"
"movl %ecx, 16(%esp)");

3) register 关键字是一个提示,编译器可能会决定将变量放在它想要的位置。另请阅读 GCC 页面上的文档,警告某些函数可能会破坏各种寄存器。 printf() 作为一个 C 函数,很可能会使用 ecx 寄存器而不保留其值。它可以保留它,但也可能不会;编译器可以使用该寄存器在该调用内部进行各种优化。它是 80x86 上的通用寄存器,通常用于各种参数传递和返回值。

未经测试的更正:

int reg; // By leaving this out, we give GCC the ability to pick the best available register.

/*
* volatile indicates to GCC that this inline assembly might do odd side
* effects and should disable any optimizations around it.
*/
asm volatile ("movl 16(%esp), %0\n\t"
"addl $4, %0\n\t"
"movl %0, 16(%esp)"
: "r" (reg)); // The "r" indicates we want to use a register

printf("Result: %d\n", reg);

GCC manage page有更多详细信息。

关于c - x86 add 和 addl 操作数相加错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35923200/

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