标签: inline-assembly

gcc 5.3 内联汇编器错误?

我有这个 32 位代码:

unsigned long long load(volatile unsigned long long *target) {
   unsigned long long result;

   __asm__ __volatile__
       (
       "movl %%ecx, %%edx\n\t"
       "movl %%ebx, %%eax\n\t"
       "lock cmpxchg8b %0\n\t"
       "movl %%edx, 4%1\n\t"
       "movl %%eax, %1\n\t"
       : "+m" (*target)
       : "o" (result)
       : "eax", "ebx", "ecx", "edx", "memory", "cc"
       );
   return result;
}
Run Code Online (Sandbox Code Playgroud)

当使用 gcc 5.3 版本编译时,代码的尾部会生成以下汇编代码(为了清晰起见,稍作编辑):

lock cmpxchg8b (%esi)
movl %edx, 48(%esp)
movl %eax, 8(%esp)
movl    8(%esp), %eax
movl    12(%esp), %edx
Run Code Online (Sandbox Code Playgroud)

调用的结果cmpxchg8b位于 EDX:EAX 中。生成的代码将 EDX 存储在 48(%esp),从 12(%esp) 重新加载 …

x86 assembly gcc inline-assembly

0
推荐指数
1
解决办法
304
查看次数

访问 C 文件中的汇编宏函数/指令

我想知道是否可以在另一个 C 文件中访问类似的汇编指令.directive或类似的宏%macro my_macro

文件:macroasm.S

%macro my_macro 1
   mov rsp, 1
%endmacro
Run Code Online (Sandbox Code Playgroud)

有没有可能的方法来调用和执行my_macroC 文件中的宏并使用 nasm 和 gcc 编译它们?

c assembly gcc nasm inline-assembly

0
推荐指数
1
解决办法
6241
查看次数

使用 gcc 内联汇编加载和存储 YMM 寄存器


我正在尝试使用 gcc 内联 asm 加载和存储 YMM 寄存器。我使用 vmovdqa 来做这件事。

为了将 __m256i 存储到特定的 YMM 寄存器(比如 YMM10),我使用以下代码

__m256i addr;
//load value to addr
asm ("vmovdqa %0,%%ymm10\n\t"
            :
            : "x" (addr)
            :);
Run Code Online (Sandbox Code Playgroud)

为了将 YMM10 中的值加载到变量,我使用以下代码

__m256i readbuff;
asm ("vmovdqa %%ymm10,%0\n\t"\
            : "=x" (readbuff)\
            :\
            :);
Run Code Online (Sandbox Code Playgroud)

我在这里面临的问题是,在我用一个值加载 YMM10 之后,我只使用了加载了值的寄存器的一半。我的意思是只加载了 128 位,另一半全为零。

我做错了什么吗?我不确定要使用什么指令 - vmovdqa、vmovaps、vmovups。请就此给我建议。

c x86 gcc inline-assembly avx2

0
推荐指数
1
解决办法
143
查看次数

x86-64 零标志在内联调用之间清除(和另一个问题)

我正在使用此处bsf找到的英特尔开发人员手册第 210 页上的x86-64 指令。本质上,如果找到最低有效位 1,则将其位索引存储在目标操作数中。

此外,如果所有源操作数为 0,则 ZF 标志设置为 1;否则,ZF 标志被清除。

我正在使用内联 x86-64 汇编指令编译我的 C 代码。我已经定义了一个调用bsf指令的 C 函数:

uint64_t bitScanForward(T_bitboard b) {
    __asm__(
       "bsf %rcx,%rax\n"
       "leave\n"
       "ret\n"
    );
}
Run Code Online (Sandbox Code Playgroud)

还有另一个 C 函数,它检查标志寄存器中 ZF 位的状态:

uint64_t isZFSet() {
    printf("\n"); <- This is another problem I am having (see below)...
    __asm__(
        "jz true\n"
        "movq $0,%rax\n"//return false
        "jmp end\n"
        "true:\n"
        "movq $1,%rax\n"//return true
        "end:\n"
        "leave\n"
        "ret\n"
    );
}
Run Code Online (Sandbox Code Playgroud)

我已经对这些进行了测试,发现即使将 bsf 命令应用于数字零,ZF 标志也始终被清除,这似乎违反了规范。

//Calling function...
//Do stuff...
bitScanForward(0ULL);//ULL is …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly gcc inline-assembly

0
推荐指数
1
解决办法
88
查看次数

如何在内联汇编中使用 INT %0 和来自 C 变量的中断号?

我想调用 bios 内联我的 c 代码。我试过了,asm("int %%al"::"a" (interrupt));但 gcc 写Error: operand size mismatch for 'int'。我想知道代码是否有效。

c x86 assembly gcc inline-assembly

0
推荐指数
1
解决办法
93
查看次数

EFLAGS 状态

在过去的几天里,我一直在为一种试图获得 EFLAGS 状态的奇怪行为而苦苦挣扎。为此,我编写了以下代码:

#include <stdio.h>

int flags_state()
{

  int flags = 0;

  __asm__ __volatile__("pushfq");
  __asm__ __volatile__("pop %%rax": "=a"(flags));

  return flags;
}

int main()
{

  printf("Returning EFLAGS state: 0x%x\n", flags_state());
  return 0;

}
Run Code Online (Sandbox Code Playgroud)

当它运行时,我得到:

./flags
Returning EFLAGS state: 0x246
Run Code Online (Sandbox Code Playgroud)

当我打印两次标志时,它变得更奇怪了

Returning EFLAGS state: 0x246
Returning EFLAGS state: 0x206
Run Code Online (Sandbox Code Playgroud)

当我尝试打印 6 次时它发生了变化

Returning EFLAGS state: 0x246
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Returning EFLAGS state: 0x202
Run Code Online (Sandbox Code Playgroud)

最后是最奇怪的(至少对我来说),当我打印 8 次时

Returning EFLAGS state: …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 inline-assembly eflags

0
推荐指数
1
解决办法
74
查看次数

如何将 asm() 与 const char* 而不是字符串文字一起使用?

如果我这样做:

const char *str = "some assembly instructions";
asm(str);
Run Code Online (Sandbox Code Playgroud)

CLion 会说“'asm' 中的预期字符串文字”

c assembly inline-assembly string-literals

0
推荐指数
1
解决办法
45
查看次数

64 位 Delphi 11 Windows 上的内联汇编器

我正在将 Windows XP 上的 Delphi 6 项目转换为 Windows 11 上的 Delphi 11。我有一个很可能很常见的问题,但不知道 Assembly 我有点困惑。

//This complies fine in 64 or 32 bit
{$IFDEF WIN32}
asm
    mov edx, aStream
    mov eax, aObject
    call aPointer
end;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
//this does not compile in 64 due to inline Assembly
{$IFDEF WIN64}
asm
    mov ecx, aStream
    mov eax, aObject
    call aPointer
end;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)

有没有好的参考资料可以帮助我快速学习?有一个简单的解决方案吗?

delphi assembly inline-assembly

0
推荐指数
1
解决办法
399
查看次数

为什么内联汇编不需要像 .data 或 .text 这样的节指令

作为一个新手,我正在遵循教程。一种是在 VS 2022 的内联汇编中将字符串中的所有字符大写:

int main()
{
    char mystr[] = "Hello World:";

    _asm
    {
        mov ecx, length mystr
    my: cmp [mystr + ecx], 'a';
        jl nocap;
        cmp [mystr + ecx], 'z';
        ja nocap;
        sub [mystr + ecx], 32;

    nocap:
    loop my
    }

    std::cout << mystr;
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么这个程序集不需要节,例如 .data、.text 或 _start:示例中可能混合了 x86 asm 和 Linux asm。

x86 assembly inline-assembly

0
推荐指数
1
解决办法
432
查看次数

为什么内联汇编不能是 constexpr?

C++ 不允许 constexpr 内联汇编有充分的理由吗?为什么 C++20 中允许未计算的内联汇编表达式?

c++ assembly inline-assembly constexpr c++20

0
推荐指数
1
解决办法
669
查看次数

标签 统计

inline-assembly ×10

assembly ×9

c ×5

gcc ×5

x86 ×5

avx2 ×1

c++ ×1

c++20 ×1

constexpr ×1

delphi ×1

eflags ×1

nasm ×1

string-literals ×1

x86-64 ×1