经过大量的互联网研究,我在我的C++程序中实现了一个小的汇编程序,用cpuid获取CPU的L1缓存大小.
int CPUID_getL1CacheSize() {
int l1CacheSize = -1;
asm ( "mov $5, %%eax\n\t" // EAX=80000005h: L1 Cache and TLB Identifiers
"cpuid\n\t"
"mov %%eax, %0" // eax into l1CacheSize
: "=r"(l1CacheSize) // output
: // no input
: "%eax" // clobbered register
);
return l1CacheSize;
}
Run Code Online (Sandbox Code Playgroud)
它适用于带有MinGW(GCC,G ++)的Windows 7 64位.接下来我在Mac计算机上使用GCC 4.0尝试了这个,因为我的程序在ComboBox中显示奇怪的字符串并且某些信号无法连接(Qt GUI),因此必定存在错误.
这是我的第一个汇编程序,希望有人能给我一个提示,谢谢!
如果我在Windows VC++中有以下代码:
DWORD somevar = 0x12345678;
_asm call dword ptr [somevar]
Run Code Online (Sandbox Code Playgroud)
如何使用AT&T语法在GCC内联汇编中做同样的事情?
__asm__ __volatile__ (
"call dword ptr [%%edx]" : :
"d" (somevar)
);
Run Code Online (Sandbox Code Playgroud)
我尝试过类似的东西,但它会产生"垃圾"错误......
然后我试图通过somevar一些寄存器,然后将其转换到dword,ptr等,但我无法得到它的工作.
更新:我找到了一些有用的东西,就好像在这种情况下我们必须使用括号而不是括号,我找到了一些lcall可以调用的东西far.但我仍然无法理解我是如何重现的dword ptr.
在gcc的CMSIS定义中,您可以找到如下内容:
static __INLINE void __DMB(void) { __ASM volatile ("dmb"); }
Run Code Online (Sandbox Code Playgroud)
我的问题是:如果内存障碍没有在clobber列表中声明"内存",它有什么用?
它是core_cm3.h中的错误还是有一个原因导致gcc在没有任何其他帮助的情况下应该正常运行?
使用Microsoft Visual C++(不是CLI,只是标准的本机C++)时,内联汇编会导致函数禁用优化吗?
当我使用IDA检查时,块外部的一些功能代码似乎确实发生了变化,但我不确定原因是什么.该函数(相对)简单,包含位操作和一些数学,但没有外部调用.
我能想到的其他可能原因是:
有任何想法吗?
我在D编程语言中使用内联汇编程序访问静态变量时遇到了一些麻烦.文档说我必须访问局部变量
mov EAX, var[EBP]; //or mov EAX, var;
Run Code Online (Sandbox Code Playgroud)
和类变量
mov EBX, this;
mov EAX, var[EBX];
Run Code Online (Sandbox Code Playgroud)
但它没有记录如何访问静态变量.这是我的代码抛出错误:
module test;
static int A = 1234;
static void SetA()
{
asm
{
mov A, 5432; //compiles, but throws an error
//tried it with "mov dword ptr [A], 5432; too
}
}
Run Code Online (Sandbox Code Playgroud)
对于可以从汇编程序和汇编程序访问的整数,我真的需要一种"全局存储"的方式,我会非常高兴有任何这方面的帮助(或替代方法).
我正在尝试做一些代码优化来消除分支,原始的c代码是
if( a < b )
k = (k<<1) + 1;
else
k = (k<<1)
Run Code Online (Sandbox Code Playgroud)
我打算用下面的汇编代码替换它
mov a, %rax
mov b, %rbx
mov k, %rcx
xor %rdx %rdx
shl 1, %rcx
cmp %rax, %rax
setb %rdx
add %rdx,%rcx
mov %rcx, k
Run Code Online (Sandbox Code Playgroud)
所以我写了内联汇编代码,如打击,
#define next(a, b, k)\
__asm__("shl $0x1, %0; \
xor %%rbx, %%rbx; \
cmp %1, %2; \
setb %%rbx; \
addl %%rbx,%0;":"+c"(k) :"g"(a),"g"(b))
Run Code Online (Sandbox Code Playgroud)
当我编译下面的代码时,我得到了错误:
operand type mismatch for `add'
operand type mismatch for `setb'
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
我正在用VC编译器编译这个C++代码.我正在尝试使用语句调用一个带有两个WORD(aka unsigned short)参数的函数__asm,如下所示:
__declspec(naked) void __stdcall CallFunction(WORD a, WORD b)
{
__asm {
PUSH EBP
MOV EBP, ESP
PUSH a
PUSH b
CALL functionAddress
LEAVE
RETN
}
}
Run Code Online (Sandbox Code Playgroud)
该功能functionAddress简单地输出结果a + b.然后调用CallFuncion(5, 5);打印"64351"或类似的东西.问题是在语句中使用a和b变量时,__asm因为这有效:
PUSH EBP
MOV EBP, ESP
PUSH 5
PUSH 5
CALL functionAddress
LEAVE
Run Code Online (Sandbox Code Playgroud)
这是以下功能functionAddress:
void __stdcall Add(WORD a, WORD b)
{
WORD c;
c = a + b;
printf("The result …Run Code Online (Sandbox Code Playgroud) 我知道使用内联汇编解决以下问题是个坏主意.我目前正在学习内联汇编作为linux内核类的一部分,这是该类的一个赋值的一部分.
下面的开头是一段几乎正确的代码片段,而不是段错误.它是一个函数,它将src从索引处开始并在索引处s_idx结束(排他地)的子字符串复制e_idx到dest仅使用内联汇编的预分配.
static inline char *asm_sub_str(char *dest, char *src, int s_idx, int e_idx) {
asm("addq %q2, %%rsi;" /* Add start index to src (ptrs are 64-bit) */
"subl %k2, %%ecx;" /* Get length of substr as e - s (int is 32-bit) */
"cld;" /* Clear direction bit (force increment) */
"rep movsb;" /* Move %ecx bytes of str at %esi into str at %edi */
: /* No Ouputs …Run Code Online (Sandbox Code Playgroud) 在Delphi的math.pas单元中有一个DivMod程序,我希望将其转换为内联并优化它,除数总是为10.但我不知道五角大楼ASM的细节.波纹管程序的转换是什么?
procedure DivMod(Dividend: Integer; Divisor: Word;
var Result, Remainder: Word);
asm
PUSH EBX
MOV EBX,EDX
MOV EDX,EAX
SHR EDX,16
DIV BX
MOV EBX,Remainder
MOV [ECX],AX
MOV [EBX],DX
POP EBX
end;
Run Code Online (Sandbox Code Playgroud) GGC的内联汇编可能难以正确实施且容易出错1。从更高层次的角度来看,内联汇编在内联汇编语句可能发出的指令之外必须考虑一些规则。
该Ç / C ++标准的考虑asm是定义的选项和实施。在GCC中记录了实现定义的行为,包括以下内容:
即使在使用volatile限定符时,也不要期望asm语句序列在编译后会保持完美连续。如果某些指令需要在输出中保持连续,请将它们放在单个多指令asm语句中。
基本的内联汇编或没有任何输出约束的扩展内联汇编都是隐式的volatile。该文档说,易失性不能保证连续的语句将按源代码中的顺序进行排序。该代码没有保证的顺序:
asm ("cli");
asm ("mov $'M', %%al; out %%al, $0xe9" ::: "eax");
asm ("mov $'D', %%al; out %%al, $0xe9" ::: "eax");
asm ("mov $'P', %%al; out %%al, $0xe9" ::: "eax");
asm ("sti");
Run Code Online (Sandbox Code Playgroud)
如果要使用CLI和STI关闭(然后重新打开)外部中断,并按顺序MDP向QEMU调试控制台(端口0xe9)输出一些字母,则不能保证。您可以将它们全部放在单个内联汇编语句中,也可以使用扩展的内联汇编模板将虚拟依赖项传递给每个保证顺序的语句。
为了使事情更易于管理,尤其是众所周知,OS开发人员会围绕此类代码创建方便的包装器。一些开发人员将其用作C预处理器宏。从理论上讲,这看起来很有用:
#define outb(port, value) \
asm ("out %0, %1" \
: \
: "a"((uint8_t)value), "Nd"((uint16_t)port))
#define cli() asm ("cli")
#define sti() asm …Run Code Online (Sandbox Code Playgroud) inline-assembly ×10
assembly ×6
gcc ×5
x86 ×5
c ×3
c++ ×3
visual-c++ ×2
cortex-m3 ×1
d ×1
delphi ×1
g++ ×1
linux ×1
osdev ×1
performance ×1