【问题标题】:Increment a number in C with an assembly instruction [duplicate]用汇编指令在C中增加一个数字[重复]
【发布时间】:2021-04-26 07:38:34
【问题描述】:

在 C 程序中直接运行汇编指令的最简单方法是什么?例如,我截取了一个示例来执行以下操作:

#include <stdio.h>

int plus_one_times_two(int x)
{
    // plus one -- in asm
    // argument passed in %rdi, so how to do: `inc %rdi` ? from C

    // times two -- in c
    x = x*2;

    return x;
}

int main(void)
{
    int x=5;
    int y=plus_one_times_two(x);
    printf("X: %d | (X+1)*2: %d\n", x, y);
}

【问题讨论】:

  • 你为什么不能只做x++;
  • @user3840170 这是一个练习,看看如何去做。我当然可以这样做,而且我什至不会使用函数,而只会内联算术:(x*2)+1
  • 为什么要在汇编中编码?在汇编中编码的原因很少。您可能想要阅读编译器生成的汇编代码!大多数笔记本电脑或台式机都是 x86-64(32 位变体 x86 在 2021 年很少见),并且大多数平板电脑都有 ARM 处理器。

标签: c assembly x86 inline-assembly


【解决方案1】:

使用asm() 进行内联汇编:

asm("inc %rdi");

请参阅this guide 了解更多信息。

编辑:正如 cmets 中所指出的,这不是你应该做的事情。您不应该在 C 代码中使用内联汇编,除非您尝试做一些在普通 C 中无法做到的特定事情,而这不是其中之一。

【讨论】:

  • @samuelbrody1249:这是完全不安全和损坏的。这会增加寄存器,但它不会告诉C 编译器您希望C 变量在RDI 中时发生这种情况,或者它会修改寄存器。有关指南的链接,请参阅 stackoverflow.com/tags/inline-assembly/info。像这样的 GNU C Basic asm 语句不能安全地用于修改 C 变量,或者除了 __attribute__((naked)) 函数的主体之外的任何东西。另见gcc.gnu.org/wiki/ConvertBasicAsmToExtended。您需要 GNU C Extended asm,就像答案中链接的指南所解释的那样!
  • @john re:您的编辑:有修改 C 变量的安全方法,例如asm("inc %0" : "+r"(var));。确实不需要为此使用内联 asm (gcc.gnu.org/wiki/DontUseInlineAsm),但这不是我的意思。更重要的是,这不是一个安全的例子。有一些安全的方法可以做到这一点,但这不是其中之一。
  • 但是,如果您想学习 asm,通常最好在 asm 中编写整个函数。一旦你理解了这一点,并使用破坏寄存器和保留寄存器调用约定,如果你出于某种原因真的想学习内联 asm,那么这就是理解如何使用 GNU C Extended asm 约束向编译器描述你的代码的良好基础。跨度>
  • @samuelbrody1249:您假设编译器将为"r" 输入(%1) 选择与"=r" 输出(%0) 相同的寄存器。这不能保证,所以你的代码很容易被破坏。阅读 GCC 手册,gcc.gnu.org/onlinedocs/gcc/Modifiers.html。或阅读此 SO 问题的各种链接的重复答案。
  • @samuelbrody1249:实际上没有一个链接副本使用+r,他们大多使用愚蠢的mov指令。见How does "+&r" differ from "+r"?。 IDK 如果您尝试使用谷歌搜索 site:stackoverflow.com inline assembly "+r" 但我做到了,并且除此之外还获得了几个点击。
猜你喜欢
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 2016-06-17
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多