我使用以下代码将cr0位设置为禁用缓存.当我编译这个
#include <stdio.h>
int main()
{
__asm__("pushl %eax\n\t"
"mov %cr0,%eax;\n\t"
"orl $(1 << 30),%eax;\n\t"
"mov %eax,%cr0;\n\t"
"wbinvd\n\t"
"popl %eax"
);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到错误说操作数对mov无效.
谁能指点我做一个好的gcc x86-64指南来做这些事情?以上代码究竟出了什么问题呢?
你好我想在一个小D程序中使用ASM:
asm
{
mov AX,12h ;
int 10h ;
}
Run Code Online (Sandbox Code Playgroud)
我从asm语句中的两行得到了这条消息:"指令结束"
我无法解决这个问题,
这就是我向你求助的原因.
感谢您的回答
我为我的英语道歉
我无法理解汇编指令retq返回的位置.
据我所知,当我的普通代码执行时,它会返回到堆栈中指定的地址.但它如何知道堆栈中的返回地址位于何处?
简而言之,它是否使用rbp或esp来查找堆栈中的地址?
下面的代码段取自Apple的ObjC运行时(libobjc)源代码.我想知道这究竟意味着什么.(不是google-able,对不起)
// HACK -- the use of these functions must be after the @implementation
id bypass_msgSend_retain(NSObject *obj) asm("-[NSObject retain]");
void bypass_msgSend_release(NSObject *obj) asm("-[NSObject release]");
id bypass_msgSend_autorelease(NSObject *obj) asm("-[NSObject autorelease]");
Run Code Online (Sandbox Code Playgroud)
更新:
以下是对bypass_msgSend_release()的调用:
movl -4(%ebp), %eax
movl %eax, (%esp)
calll "-[NSObject release]"
Run Code Online (Sandbox Code Playgroud) 背景:我的任务是为Unitech HT630编写一个数据收集程序,它运行一个专有的DOS操作系统,可以运行为16位MS DOS编译的可执行文件,尽管有一些限制.我正在使用Digital Mars C/C++编译器,它似乎运行得很好.
对于某些我可以使用标准C库的东西,但是在单元的屏幕上绘制等其他东西需要汇编代码.设备文档中给出的汇编示例与我在C/C++中使用内联汇编代码的方式不同.作为参考,BYTE在以下示例中是类型unsigned char.
给出了示例代码的示例:
#include <dos.h>
/* Set the state of a pixel */
void LCD_setpixel(BYTE x, BYTE y, BYTE status) {
if(status > 1 || x > 63 || y > 127) {
/* out of range, return */
return;
}
/* good data, set the pixel */
union REGS regs;
regs.h.ah = 0x41;
regs.h.al = status;
regs.h.dh = x;
regs.h.dl = y;
int86(0x10, ®s, ®s);
}
Run Code Online (Sandbox Code Playgroud)
我如何被教导使用内联汇编:
/* …Run Code Online (Sandbox Code Playgroud) 我试图在gcc中混合使用SSE2内在函数和内联汇编程序.但是如果我将变量指定为xmm0/register作为输入,那么在某些情况下我会遇到编译器错误.例:
#include <emmintrin.h>
int main() {
__m128i test = _mm_setzero_si128();
asm ("pxor %%xmm0, %%xmm0" : : "xmm0" (test) : );
}
Run Code Online (Sandbox Code Playgroud)
使用gcc版本4.6.1编译时,我得到:
>gcc asm_xmm.c
asm_xmm.c: In function ‘main’:
asm_xmm.c:10:3: error: matching constraint references invalid operand number
asm_xmm.c:7:5: error: matching constraint references invalid operand number
Run Code Online (Sandbox Code Playgroud)
奇怪的是,在我有其他输入变量/寄存器的相同情况下,它突然使用xmm0作为输入而不是xmm1等.而在另一种情况下,我能够指定xmm0-xmm4但不能在上面.对此有点困惑/沮丧:S
谢谢 :)
我正在学习x86内联汇编编程.
我想写mov ecx, FFFFFFBB,但编译器没有认识到它.这样的十六进制数应该如何用内联汇编代码编写?
所以我在一段时间后自学了x86程序集,只是在C++中使用内联汇编.
所以我想做的是在函数参数,传入数组,索引(unsigned int)和数字.使用程序集,它会将数组的内存位置中的值更改为传入的值.所以代码看起来像这样.
inline void Set( int pArray[], unsigned int pIndex, int pNum ) {
__asm {
mov ebx, pIndex
mov eax, 4
mul ebx
mov ebx, pNum
lea edi, pArray
mov [ edi + eax ], ebx
}
}
int main() {
int myArray[ 5 ] = { 1, 2, 3, 4, 5 };
Set( myArray, 2, 7 );
std::cout << myArray[ 2 ] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
所以代码应该加载数组地址的开头,获取索引并将其乘以4,以便内存位置移动那么多字节,然后将其更改为传入的值.但是,当我这样做时,值保持不变.这是为什么?出了什么问题?
我正在将一些遗留汇编代码移植到 Rust,我需要通过asm!宏调用它。然而,汇编代码依赖于 C 头文件中存储的一些常量。我想保持类似,在 Rust 中定义常量,并在宏中包含常量的名称asm。
旧版 C 标头:
#define HCR_VALUE 0xffff0000
Run Code Online (Sandbox Code Playgroud)
旧版 ASM 文件:
.func
...
ldr x0, =HCR_VALUE
...
Run Code Online (Sandbox Code Playgroud)
铁锈代码:
pub const HCR_VALUE: u32 = 0xffff0000;
Run Code Online (Sandbox Code Playgroud)
unsafe { asm!("ldr x0, HCR_VALUE":::"x0"); }
Run Code Online (Sandbox Code Playgroud)
构建应用程序最终会出现链接器错误:
lld-link: error: undefined symbol: HCR_VALUE
Run Code Online (Sandbox Code Playgroud) 受到最近一个问题的启发。
gcc 式内联汇编的一种用例是对编译器和汇编器都不知道的指令进行编码。例如,我给出了如何在太旧而无法支持的工具链上使用指令的示例:rdrand
/* "rdrand %%rax ; setc %b1" */
asm volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %b1"
: "=a"(result), "=qm"(success) :: "cc");
Run Code Online (Sandbox Code Playgroud)
不幸的是,对指令进行硬编码意味着您还需要对其使用的寄存器进行硬编码,从而大大减少了编译器执行寄存器分配的自由度。
在某些架构上(例如带有.insn指令的 RISC-V),汇编器提供了一种系统地构建原始指令的方法,但这似乎是例外。
一个简单的解决方案是有一种方法来获取寄存器的未修饰编号,以将其手动编码到指令中。例如,假设X存在模板修饰符来打印所选寄存器的编号。那么,上面的例子可以变得更加灵活:
/* "rdrand %0 ; setc %b1" */
asm volatile (".byte 0x48 | (%X0 >> 3), 0x0f, 0xc7, 0xf0 | (%X0 & 7); setc %b1"
: "=r"(result), "=qm"(success) :: "cc");
Run Code Online (Sandbox Code Playgroud)
同样,如果有一种方法可以让 gcc 打印12而不是v12ARM64 上的 SIMD 寄存器 12,则可以执行如下操作:
float32x4_t add3(float32x4_t a, float32x4_t b) …Run Code Online (Sandbox Code Playgroud)