标签: inline-assembly

如何在iPhone上进行内联汇编?

怎么做?我需要采取哪些步骤以及需要考虑哪些陷阱和陷阱?

iphone assembly inline-assembly

29
推荐指数
2
解决办法
1万
查看次数

64位应用程序和内联汇编

我正在使用Visual C++ 2010开发32位Windows应用程序.有一些我真的想要使用内联汇编.但我刚刚意识到Visual C++不支持64位应用程序中的内联汇编.因此,将来移植到64位是一个大问题.

我不知道64位应用程序与32位应用程序有何不同.是否有可能在未来将32位应用程序全部升级到64位?我听说64位CPU有更多的寄存器.由于性能不是我的应用程序的问题,使用这些额外的寄存器不是我的问题.32位应用程序是否需要升级到64位还有其他原因吗?与32位应用程序相比,64位应用程序处理的方式是否有所不同,除了64位应用程序可能使用64位CPU独有的寄存器或指令?

我的应用程序需要与其他操作系统组件进行交互,例如驱动程序,我知道它必须是64位窗口中的64位.我的32位应用程序是否与它们兼容?

c++ windows 64-bit inline-assembly visual-c++

27
推荐指数
3
解决办法
3万
查看次数

标签地址(MSVC)

我们正在为高级编译语言编写一个字节码,经过一些分析和优化后,很明显当前最大的性能开销是我们用来跳转到字节码情况的switch语句.

我们调查了拉出每个case标签的地址并将其存储在字节码本身的流中,而不是我们通常打开的指令ID.如果我们这样做,我们可以跳过跳转表,并直接跳转到当前正在执行的指令的代码位置.这在GCC中非常有用,但是,MSVC似乎不支持这样的功能.

我们尝试使用内联汇编来获取标签的地址(并跳转到它们),但它可以工作,但是,使用内联汇编会导致MSVC优化器避免使用整个函数.

有没有办法让优化器仍然运行代码?遗憾的是,我们无法将内联汇编提取到另一个函数中,而不是制作标签的函数,因为即使在内联汇编中也无法为另一个函数引用标签.有什么想法或想法吗?非常感谢您的意见,谢谢!

c++ assembly label goto inline-assembly

25
推荐指数
2
解决办法
5643
查看次数

内联装配破坏了红色区域

我正在编写一个加密程序,并且核心(一个宽的乘法例程)是用x86-64汇编编写的,两者都是为了速度而且因为它广泛使用adc那些不容易从C中访问的指令.我不想内联这个函数,因为它很大,并且在内循环中被调用了好几次.

理想情况下,我还想为此函数定义一个自定义调用约定,因为它在内部使用所有寄存器(除外rsp),不破坏其参数,并在寄存器中返回.现在,它适应了C调用约定,但当然这使它变慢(大约10%).

为了避免这种情况,我可以调用它,asm("call %Pn" : ... : my_function... : "cc", all the registers);但有没有办法告诉GCC调用指令与堆栈混淆?否则GCC会将所有这些寄存器放在红色区域中,而顶部的寄存器将被破坏.我可以使用-mno-red-zone编译整个模块,但是我更喜欢告诉GCC,比方说,红色区域的前8个字节将被破坏,以便它不会放任何东西.

c x86 gcc inline-assembly red-zone

20
推荐指数
2
解决办法
1716
查看次数

是否可以在Swift中编写内联汇编?

我想知道你是否可以在Swift中编写内联汇编.

我知道在Objective-C中你可以使用这样的东西:

inline void assemblyFunc() {
    __asm__(/*Assembly*/);
}
Run Code Online (Sandbox Code Playgroud)

但在Swift中似乎你无法使用 __asm__(/*Assembly*/).

__asm__()如果有可能,有谁知道如何使用.我还没有找到任何关于它的信息,所以我认为这是一个很好的问题.

inline-assembly swift

19
推荐指数
2
解决办法
4006
查看次数

GCC内联汇编:约束

我很难理解角色约束在GCC内联汇编(x86)中的作用.我已经阅读了手册,它准确地解释了每个约束的作用.问题在于,即使我理解每个约束的作用,我也很少理解为什么要使用一个约束而不是另一个约束,或者含义可能是什么.

我意识到这是一个非常广泛的话题,所以一个小例子应该有助于缩小焦点.以下是一个简单的asm例程,它只添加了两个数字.如果发生整数溢出,则将值写入1输出C变量.

 int32_t a = 10, b = 5;
 int32_t c = 0; // overflow flag

 __asm__
 (
  "addl %2,%3;"        // Do a + b (the result goes into b)
  "jno 0f;"            // Jump ahead if an overflow occurred
  "movl $1, %1;"       // Copy 1 into c
  "0:"                 // We're done.

  :"=r"(b), "=m"(c)    // Output list
  :"r"(a), "0"(b)     // Input list
 );
Run Code Online (Sandbox Code Playgroud)

现在这个工作正常,除了我必须随意摆弄约束,直到我让它正常工作.最初,我使用了以下约束:

  :"=r"(b), "=m"(c)    // Output list
  :"r"(a), "m"(b)     // Input list
Run Code Online (Sandbox Code Playgroud)

请注意,我使用"m"约束而不是"0" b.这有一个奇怪的副作用,如果我用优化标志编译并调用该函数两次,由于某种原因,加法操作的结果也将被存储 …

c c++ gcc constraints inline-assembly

17
推荐指数
1
解决办法
4928
查看次数

gcc删除内联汇编程序代码

似乎gcc 4.6.2删除了它认为从函数中未使用的代码.

test.c的

int main(void) {
  goto exit;
  handler:
    __asm__ __volatile__("jmp 0x0");
  exit:
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

拆卸 main()

   0x08048404 <+0>:     push   ebp
   0x08048405 <+1>:     mov    ebp,esp
   0x08048407 <+3>:     nop    # <-- This is all whats left of my jmp.
   0x08048408 <+4>:     mov    eax,0x0
   0x0804840d <+9>:     pop    ebp
   0x0804840e <+10>:    ret
Run Code Online (Sandbox Code Playgroud)

编译器选项

没有启用优化,只是gcc -m32 -o test test.c(-m32因为我在64位机器上).

我怎么能阻止这种行为?

编辑:最好通过使用编译器选项,而不是通过修改代码.

c x86 gcc inline-assembly compiler-optimization

17
推荐指数
3
解决办法
2357
查看次数

使用背靠背rdtsc进行负时钟周期测量?

我正在编写一个C代码,用于测量获取信号量所需的时钟周期数.我正在使用rdtsc,在对信号量进行测量之前,我连续两次调用rdtsc来测量开销.我在for循环中重复了这么多次,然后我将平均值用作rdtsc开销.

这是正确的,首先要使用平均值吗?

尽管如此,这里的一个大问题是,有时我会得到开销的负值(不一定是平均值,但至少是for循环中的部分值).

这也影响了连续计算sem_wait()操作所需的cpu周期数,有时也证明是负数.如果我写的不清楚,这里有一部分我正在编写的代码.

为什么我会得到这样的负值?


(编者注:请参阅获取CPU周期计数?以获得完整的64位时间戳的正确和可移植方式."=A"编译为x86-64时,asm约束只能得到低或高32位,具体取决于寄存器分配是否发生为uint64_t输出选择RAX或RDX .它不会选择edx:eax.)

(编辑的第二个注释:哎呀,这就是为什么我们得到负面结果的答案.仍然值得留下一个注释作为警告,不要复制这个rdtsc实现.)


#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

static inline uint64_t get_cycles()
{
  uint64_t t;
           // editor's note: "=A" is unsafe for this in x86-64
  __asm volatile ("rdtsc" : "=A"(t));
  return t;
}

int num_measures = 10;

int main ()
{
   int i, value, res1, res2;
   uint64_t c1, c2;
   int tsccost, tot, a;

   tot=0;    

   for(i=0; i<num_measures; i++)
   { …
Run Code Online (Sandbox Code Playgroud)

c x86-64 overhead inline-assembly rdtsc

17
推荐指数
3
解决办法
1万
查看次数

Clang 是否为内联汇编生成了错误的代码?

我有一些 C 代码:

#include "stdio.h"

typedef struct num {
    unsigned long long x;
} num;

int main(int argc, char **argv) {
    struct num anum;
    anum.x = 0;
    __asm__("movq %%rax, %0\n" : "=m" (anum.x) : "rax"(2));
    printf("%llu\n",anum.x);
}
Run Code Online (Sandbox Code Playgroud)

我正在我的(英特尔)Mac 笔记本电脑上编译并运行它。

代码的输出似乎有所不同,具体取决于我使用 (GNU) GCC 还是 Clang 进行编译。gnucc -o gnu-test test.c我使用GCC(从https://gcc.gnu.org/install/download.htmlgnucc下载源代码后在 Mac 上从源代码构建)和Clang(内置 macOS Clang)进行编译。clang -o clang-test test.c

在我的 Mac 上,使用 GNU,结果是2(这是我所期望的)。使用 Clang,结果是140701838959608.

Clang 结果对我来说似乎是错误的,但我也想知道我的内联汇编是否不太正确,而 GCC 恰好没有暴露我的错误。

我在Compiler Explorer上尝试了相同的代码, GCC(x86-64 GCC 13.2 …

c clang inline-assembly

17
推荐指数
1
解决办法
1378
查看次数

GCC内联汇编:在intel x86_64上注册约束

这是寄存器加载代码列表:

a eax
b ebx
c ecx
d edx
S esi
D edi
I常数值(0到31)
q,r动态分配寄存器(见下文)
g eax,ebx,ecx,edx或内存中
的变量a eax和edx合并为64位整数(使用long longs)

但这是intel i386的注册限制.我的问题是我可以在哪里找到intel x86_64系统的寄存器限制,例如:

?%r10
?%r8
?%的RDX

等等.

assembly gcc x86-64 inline-assembly

15
推荐指数
2
解决办法
8901
查看次数