gpt4 book ai didi

c - 使用内存引用的 GCC 内联汇编程序

转载 作者:太空宇宙 更新时间:2023-11-04 04:21:45 25 4
gpt4 key购买 nike

我正在尝试编写一个内联汇编指令,该指令将通过使用指向该变量的指针而不是直接引用来加载具有寄存器内容的变量。

使用直接引用的代码工作正常,看起来像这样:

int x;
int *y = &x;
int z = 1;

__asm__ __volatile__ ("mov %%edx, %0;"::"r"(z):);
__asm__ __volatile__ ("mov %0, %%edx;":"=r" (x)::);
printf("\n%x\n", x);

反对:

0x000000000040052d <+0>:     push   %rbp  
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x10,%rsp
0x0000000000400535 <+8>: lea -0x10(%rbp),%rax
0x0000000000400539 <+12>: mov %rax,-0x8(%rbp)
0x000000000040053d <+16>: movl $0x1,-0xc(%rbp)
0x0000000000400544 <+23>: mov -0xc(%rbp),%eax
0x0000000000400547 <+26>: mov %edx,%eax
0x0000000000400549 <+28>: mov %eax,%edx
0x000000000040054b <+30>: mov %eax,-0x10(%rbp)
0x000000000040054e <+33>: mov -0x10(%rbp),%eax
0x0000000000400551 <+36>: mov %eax,%esi
0x0000000000400553 <+38>: mov $0x4005f4,%edi
0x0000000000400558 <+43>: mov $0x0,%eax
0x000000000040055d <+48>: callq 0x400410 <printf@plt>
0x0000000000400562 <+53>: mov $0x0,%eax
0x0000000000400567 <+58>: leaveq
0x0000000000400568 <+59>: retq

它按预期输出 1

指针版本如下所示:

int x;
int *y = &x;
int z = 1;

__asm__ __volatile__ ("mov %%edx, %0;"::"r"(z):);
__asm__ __volatile__ ("mov (%0), %%edx;":"+r" (y)::);
//or
__asm__ __volatile__ ("mov %[mem], %%edx":[mem] "=m" (y)::);
printf("\n%x\n", x);

反对:

0x000000000040052d <+0>:     push   %rbp
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x10,%rsp
0x0000000000400535 <+8>: lea -0x10(%rbp),%rax
0x0000000000400539 <+12>: mov %rax,-0x8(%rbp)
0x000000000040053d <+16>: movl $0x1,-0xc(%rbp)
0x0000000000400544 <+23>: mov -0xc(%rbp),%eax
0x0000000000400547 <+26>: mov %edx,%eax
0x0000000000400549 <+28>: mov -0x8(%rbp),%edx
0x000000000040054c <+31>: mov -0x10(%rbp),%eax
0x000000000040054f <+34>: mov %eax,%esi
0x0000000000400551 <+36>: mov $0x4005f4,%edi
0x0000000000400556 <+41>: mov $0x0,%eax
0x000000000040055b <+46>: callq 0x400410 <printf@plt>
0x0000000000400560 <+51>: mov $0x0,%eax
0x0000000000400565 <+56>: leaveq
0x0000000000400566 <+57>: retq

这每次都会打印一个不确定的整数(即 bb524b90 15979050)。当在 gdb 中运行时,它每次都打印相同的整数 (ffffe2f0),它不会根据 z 的值而改变。有谁知道是什么原因造成的?

最佳答案

I am getting output from the reg, not input, notice the argument positioning "mov %0, %%edx;":"=r" (x)::

您对输入/输出术语感到困惑。

输出操作数是 asm 语句的输出编译器选择的寄存器(对于 "= r" 大小写).

当您使用 "=m" 时,编译器会将 %0 设为内存操作数。

或者,如果您使用 "=a"%0 将是 %eax,并且编译器会假定C 变量 x 现在位于 %eax 中。


在 AT&T 语法中,目标操作数是最后一个操作数。我想您确实知道这一点,但我认为您的输入/输出倒退了。

关于c - 使用内存引用的 GCC 内联汇编程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46206719/

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