我有这个 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) 重新加载 …
我想知道是否可以在另一个 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 编译它们?
为了将 __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。请就此给我建议。
我正在使用此处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) 我想调用 bios 内联我的 c 代码。我试过了,asm("int %%al"::"a" (interrupt));但 gcc 写Error: operand size mismatch for 'int'。我想知道代码是否有效。
在过去的几天里,我一直在为一种试图获得 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) 如果我这样做:
const char *str = "some assembly instructions";
asm(str);
Run Code Online (Sandbox Code Playgroud)
CLion 会说“'asm' 中的预期字符串文字”
我正在将 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)
有没有好的参考资料可以帮助我快速学习?有一个简单的解决方案吗?
作为一个新手,我正在遵循教程。一种是在 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。
C++ 不允许 constexpr 内联汇编有充分的理由吗?为什么 C++20 中允许未计算的内联汇编表达式?