使用内联汇编在C中添加值(Adding values in C using inline assembly)

编程入门 行业动态 更新时间:2024-10-27 04:31:46
使用内联汇编在C中添加值(Adding values in C using inline assembly)

我试图掌握C(ATT装配)中内联装配的基础知识,所以我通过添加2个变量来练习。

好的,这样可以按预期工作; 将src变量复制到dst变量,然后将dst变量添加为5.srcdst的值分别为1和6。

int src = 1; int dst = 0; asm ("mov %[SRC], %[DEST]\n\t" "add $5, %0" : [DEST] "=r" (dst)); : [SRC] "r" (src));

但是当我尝试这个时, srcdst的值仍然是1和6.我希望src的值为1, dst的值为5,因为将dst加5(自MOV以来值为0)操作已被删除)应该有输出5。

int src = 1; int dst = 0;

asm ("add $5, %[DEST]" : [DEST] "=r" (dst) : [SRC] "r" (src));

因此,我尝试使用以下代码将src作为输入操作数删除,但现在dst获取值11。

int dst = 0; asm ( "add $5, %[DEST]" : [DEST] "=r" (dst));

现在我有点困惑它是如何工作的。 我有什么误会?

Im trying to get a grasp on the basics of inline assembly in C (ATT assembly), so Im practicing by adding 2 variables.

Ok so this works as intended; the src variable gets copied to the dst variable and then the dst variable gets added by 5. The values of src and dst are 1 and 6 respectively.

int src = 1; int dst = 0; asm ("mov %[SRC], %[DEST]\n\t" "add $5, %0" : [DEST] "=r" (dst)); : [SRC] "r" (src));

But when I try this out, the values of src and dst are still 1 and 6. I was expecting src to have the value 1 and dst to have the value 5 since adding 5 to dst (which has the value of 0 since the MOV operation has been removed) should have the output 5.

int src = 1; int dst = 0;

asm ("add $5, %[DEST]" : [DEST] "=r" (dst) : [SRC] "r" (src));

So I then try removing the src as an input operand using the following code, but now dst gets the value 11.

int dst = 0; asm ( "add $5, %[DEST]" : [DEST] "=r" (dst));

Now I'm a bit confused how it works. What am I misunderstanding?

最满意答案

代码的第一部分按预期工作。 那里

mov %[SRC], %[DEST] ; copies %[SRC] into %[DEST], which is now 1 add $5, %0 ; adds 5 to %0 (which is %[DEST]), so that's 6

第二部分不起作用,因为你从不使用%[SRC] ,并且因为%[DEST]不是输入操作数,所以它的值不会进入计算。 你只是得到了gcc决定使用的寄存器。 第三部分出于同样的原因失败了。

要使其工作,您需要将dst指定为输入和输出操作数,因为您既使用其值又更改它。 但是,这不起作用:

asm("add $5, %0" // This does not work! : "=r" (dst) : "r" (dst));

因为现在你有一个带有值dst的输入操作数%1和一个不同的输出操作数%0其值将被写入dst ,你永远不会使用%1 。 这种表示法可以让你写

asm("mov %1, %0; add $5, %0" // needlessly inefficient! : "=r" (dst) : "r" (dst));

但那当然是不必要的低效率。 要使用单个寄存器执行此操作,您需要使用匹配的约束,如下所示:

asm("add $5, %0" : "=r" (dst) : "0" (dst));

这告诉gcc允许%0作为输入操作数,并且它具有dst的值。 这是gcc手册的相关部分。

最后,使用命名操作数,它看起来像这样:

asm ("add $5, %[DEST]" : [DEST] "=r" (dst) : "[DEST]" (dst));

The first part of your code works as expected. There

mov %[SRC], %[DEST] ; copies %[SRC] into %[DEST], which is now 1 add $5, %0 ; adds 5 to %0 (which is %[DEST]), so that's 6

The second part does not work because you never use %[SRC], and because %[DEST] is not an input operand, so its value doesn't come into the calculation. You just get what happens to be in the register gcc decides to use. The third part fails for the same reason.

For it to work, you need to specify dst as both an input and output operand, since you're both using its value and changing it. However, this does not work:

asm("add $5, %0" // This does not work! : "=r" (dst) : "r" (dst));

because now you have an input operand %1 with value dst and a distinct output operand %0 whose value will be written to dst, and you never use %1. This notation would allow you to write

asm("mov %1, %0; add $5, %0" // needlessly inefficient! : "=r" (dst) : "r" (dst));

but that is, of course, needlessly inefficient. In order to do this with a single register, you need to use a matching constraint like this:

asm("add $5, %0" : "=r" (dst) : "0" (dst));

This tells gcc that %0 as an input operand is allowed, and that it has the value of dst. Here is the relevant part of the gcc manual.

With named operands, finally, it looks like this:

asm ("add $5, %[DEST]" : [DEST] "=r" (dst) : "[DEST]" (dst));

更多推荐

本文发布于:2023-07-06 07:53:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1047542.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:内联   Adding   values   inline   assembly

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!