标签: inline-assembly

内联汇编的初学者问题

我正在使用 VS2008 C++(无库)。这是我的代码:

    __asm
    {
    jmp start
msg:
          db "http://www.stackoverflow.com"
dtfld:
          db "00/00/0000"
tmfld:
          db "00:00:00"
start:
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

错误 1 ​​错误 C2400:“操作码”中内联汇编器语法错误;发现“错误标记”
错误 2 错误 C2400:“操作码”中存在内联汇编器语法错误;发现“错误标记”
错误 3 错误 C2400:“操作码”中内联汇编器语法错误;发现“坏令牌”

为什么是这样?

assembly inline-assembly visual-c++

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

访问嵌入式 X86 汇编中的特定位

我正在尝试访问特定位并修改它。我已将 0x01ABCDEF(十六进制值)移至 ecx 中,并希望能够检查特定位置的位值。例如,我必须取 0x01ABCDEF (0xEF) 的字节 0 检查位置 7 处的位是否为 1,将中间 4 位设置为 1,其余设置为 0。

x86 assembly inline-assembly visual-studio-2010

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

preempt_disable/enable 和 raw_local_irq_save/restore 在基准测试中的作用

英特尔 (链接)的以下论文描述了一种对代码进行准确基准测试的方法。基准测试的核心内容如下(参见第 31 页):

preempt_disable();
raw_local_irq_save(flags);

asm volatile ( 
    "CPUID\n\t" 
    "RDTSC\n\t" 
    "mov %%edx, %0\n\t" 
    "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low):: "%rax", "%rbx", "%rcx", "%rdx"
);

/*call the function to measure here*/ 

asm volatile( 
    "CPUID\n\t" 
    "RDTSC\n\t" 
    "mov %%edx, %0\n\t"
    "mov %%eax, %1\n\t": "=r" (cycles_high1), "=r" (cycles_low1):: "%rax", "%rbx", "%rcx", "%rdx"
); 

raw_local_irq_restore(flags);  
preempt_enable(); 
Run Code Online (Sandbox Code Playgroud)

我想知道:

  • 做什么raw_local_irq_save和raw_local_irq_restore做什么?
  • 做什么preempt_disable和preempt_enable做什么?
  • 他们在特定背景下的作用是什么?
  • 从基准测试代码中删除它们会产生什么后果?它会阻止正确的基准测试吗?什么可能出错?

c c++ benchmarking kernel inline-assembly

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

带堆栈操作的 GCC 内联汇编

我需要这样的内联汇编代码:

  • 我在组件内部有一对(所以,它是平衡的)推/弹出操作
  • 我在内存中也有一个变量(所以,不是注册)作为输入

像这样:

__asm__ __volatile__ ("push %%eax\n\t"
        // ... some operations that use ECX as a temporary
        "mov %0, %%ecx\n\t"
        // ... some other operation
        "pop %%eax"
: : "m"(foo));
// foo is my local variable, that is to say, on stack
Run Code Online (Sandbox Code Playgroud)

反汇编编译后的代码时,编译器给出的内存地址是0xc(%esp),它是相对于 的esp,因此,由于我push之前有一个操作,这段代码将无法正常工作mov。因此,我怎么能告诉编译器我不喜欢foo相对于esp,但像-8(%ebp)相对于 ebp 的任何东西。

PS 你可能会建议我可以放在eaxClobbers 里面,但这只是一个示例代码。我不想展示我不接受此解决方案的完整原因。

x86 assembly gcc inline-assembly

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

在内联汇编中使用特定的 zmm 寄存器

我可以告诉gcc 风格的内联汇编将我的__m512i变量放入特定的 zmm寄存器中,例如zmm31?

x86 assembly gcc inline-assembly

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

如何为 gcc 内联 asm 获取 64 位整数的较低和较高 32 位?(ARMV5平台)

我在armv5te平台上有一个项目,我要重写一些函数并使用汇编代码来使用增强型DSP指令。我为累加器使用了很多 int64_t 类型,但我不知道如何将它传递给 arm 指令 SMULL ( http://www.keil.com/support/man/docs/armasm/armasm_dom1361289902800.htm )。

如何将 64 个变量的较低或较高 32 位传递给 32 位寄存器?(我知道,我可以使用中间变量 int32_t,但它看起来不太好)。

我知道,那个编译器会为我做这件事,但我只是写了一个小函数作为例子。

int64_t testFunc(int64_t acc, int32_t x, int32_t y)
{
   int64_t tmp_acc;

   asm("SMULL %0, %1, %2, %3"
      : "=r"(tmp_acc), "=r"(tmp_acc) // no idea how to pass tmp_acc;
      : "r"(x), "r"(y)
      );

return tmp_acc + acc;
}
Run Code Online (Sandbox Code Playgroud)

c assembly gcc arm inline-assembly

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

如何在 ARM aarch64 GCC 内联汇编中使用 32 位 w 寄存器?

我可以使用 64 位寄存器,例如:

#include <assert.h>
#include <inttypes.h>

int main(void) {
    uint64_t io = 1;
    __asm__ (
        "add %[io], %[io], 1;"
        : [io] "+r" (io)
        :
        :
    );
    assert(io == 2);
}
Run Code Online (Sandbox Code Playgroud)

它编译和反汇编:

aarch64-linux-gnu-gcc -ggdb3 -o main.out main.c
gdb-multiarch -batch -ex 'disassemble/rs main' main.out
Run Code Online (Sandbox Code Playgroud)

按预期到 64 位寄存器:

6           __asm__ (
   0x0000000000000744 <+16>:    a0 0f 40 f9     ldr     x0, [x29, #24]
   0x0000000000000748 <+20>:    00 04 00 91     add     x0, x0, #0x1
   0x000000000000074c <+24>:    a0 0f 00 f9     str     x0, [x29, #24]
Run Code Online (Sandbox Code Playgroud)

如何改用 …

gcc arm inline-assembly arm64

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

为什么预处理器需要大括号才能有语句?

有这个代码:

#define GREATER(a, b, res) ( \ /* no braces here */
    asm("cmp %1, %2\n\t" \
         "jge 0f\n\t" \
         "movl %1, %0\n\t" \
         "jmp 1f\n" \
         "0:\n\t" \
         "movl %2, %0\n" \
         "1:" \
         : "=r"(res) \
         : "r"(a), "r"(b)); )
Run Code Online (Sandbox Code Playgroud)

错误: c.c:4:2: error: expected expression before ‘asm’ asm("cmp %1, %2\n\t" \

但是这个(只更改了大括号,其他所有内容都保留了 - 代码在其他方面是正确的):

#define GREATER(a, b, res) ({ \ /* used braces here - correct */
    asm("cmp %1, %2\n\t" \
         "jge 0f\n\t" \
         "movl %1, %0\n\t" \
         "jmp …
Run Code Online (Sandbox Code Playgroud)

c preprocessor inline-assembly

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

x86 中哪些 MOV 指令未使用或最少使用,可用于自定义 MOV 扩展

我正在 gem5 模拟器中的 X86 架构中对自定义 MOV 指令进行建模,为了在模拟器上测试其实现,我需要使用内联汇编来编译 C 代码以创建二进制文件。但由于它是一条自定义指令,尚未在 GCC 编译器中实现,因此编译器会抛出错误。我知道一种方法是扩展 GCC 编译器以接受我的自定义 X86 指令,但我不想这样做,因为它更耗时(但稍后会这样做)。

作为临时黑客(只是为了检查我的实现是否值得)。我想编辑已经存在的 MOV 指令,同时更改模拟器中的底层“微操作”,以便欺骗 GCC 接受我的“自定义”指令并进行编译。

因为 x86 架构中有多种类型的 MOV 指令。因为它们是86架构参考中的各种MOV指令。

因此,我的问题是,哪条 MOV 指令使用最少,我可以编辑其底层微操作。假设我的工作负载仅包括整数,即很可能不会使用 xmm 和 mmx 寄存器,并且我的指令反映了 MOV 指令的相同实现。

x86 gcc machine-code inline-assembly gem5

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

关于手臂内联装配的不同 clobber 描述的混淆

我正在学习ARM内联汇编,并且对一个非常简单的函数感到困惑:将值分配给xto y(两者都是int类型),在arm32和arm64上为什么需要不同的clobber描述?

这是代码:

#include <arm_neon.h>
#include <stdio.h>

void asm_test()
{
    int x = 10;
    int y = 0;

#ifdef __aarch64__
    asm volatile(
        "mov %w[in], %w[out]"
        : [out] "=r"(y)
        : [in] "r"(x)
        : "r0" // r0 not working, but r1 or x1 works
    );
#else
    asm volattile(
        "mov %[in], %[out]"
        : [out] "=r"(y)
        : [in] "r"(x)
        : "r0"    // r0 works, but r1 not working
    );
#endif
    printf("y is %d\n", y);
}

int main() { …
Run Code Online (Sandbox Code Playgroud)

gcc arm inline-assembly arm64

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