假设我们有以下c ++代码:
int var1;
__asm {
mov var1, 2;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想知道的是,如果我不想在__asm指令之外定义var1,我需要做些什么才能把它放在里面.它甚至可能吗?
谢谢
将内联汇编程序插入到类似C语言的函数中时,关于允许哪些寄存器用于临时的约定是什么?编译器是否有责任在进入asm块之前保存需要保存的所有寄存器的值?程序员是否有责任将值存储在这些寄存器中并在退出asm块之前恢复它们?是否有典型的约定,或者这是特定于实现的?
我对内联汇编程序有疑问.可以在同一个函数中从内联汇编程序调用另一个汇编程序子程序吗?例如:
void FindValidPID(unsigned int &Pid)
{
__asm
{
sub esp, 20h
mov eax, Pid
add eax,eax
call sub123 ; another assm subroutine
mov Pid, eax
add esp, 20h
}
}
Run Code Online (Sandbox Code Playgroud)
在哪里,以及如何编写子程序sub123?
干杯,
托马斯
我还在和GCC打架- 编译下面的内联汇编代码(带-fasm-blocks,它启用了英特尔风格的汇编语法)给我一个奇怪的错误不能取'this'的地址,这是一个rvalue表达式 ...
MyClass::MyFunction()
{
_asm
{
//...
mov ebx, this // error: Cannot take the address of 'this', which is an rvalue expression
//...
mov eax, this // error: Cannot take the address of 'this', which is an rvalue expression
//...
};
}
Run Code Online (Sandbox Code Playgroud)
为什么我可以将指针存储到寄存器中的不同对象,但是不能使用指向MyClass实例的指针?
我正在尝试为高度优化的x86-64位操作代码编写一个小型库,并且正在摆弄内联asm.
在测试这个特殊情况时引起了我的注意:
unsigned long test = 0;
unsigned long bsr;
// bit test and set 39th bit
__asm__ ("btsq\t%1, %0 " : "+rm" (test) : "rJ" (39) );
// bit scan reverse (get most significant bit id)
__asm__ ("bsrq\t%1, %0" : "=r" (bsr) : "rm" (test) );
printf("test = %lu, bsr = %d\n", test, bsr);
Run Code Online (Sandbox Code Playgroud)
在gcc和icc中编译并运行良好,但是当我检查程序集时,我会得到差异
gcc -S -fverbose-asm -std=gnu99 -O3
movq $0, -8(%rbp)
## InlineAsm Start
btsq $39, -8(%rbp)
## InlineAsm End
movq -8(%rbp), %rax
movq %rax, -16(%rbp)
## …Run Code Online (Sandbox Code Playgroud) 我试图从c调用汇编函数,但我不断收到错误.
.text
.globl integrate
.type integrate, @function
integrate:
push %ebp
mov %esp, %ebp
mov $0,%edi
start_loop:
cmp %edi,1024
je loop_exit
mov 8(%ebp),%eax
mov 12(%ebp),%ecx
sub %eax,%ecx
add %edi,%ecx
incl %edi
jmp start_loop
loop_exit:
movl %ebp, %esp
popl %ebp
ret
Run Code Online (Sandbox Code Playgroud)
这是我的汇编函数,名为integrate.s的文件.
#include <stdio.h>
extern int integrate(int from,int to);
void main()
{
printf("%d",integrate(1,10));
}
Run Code Online (Sandbox Code Playgroud)
继承人我的代码.
function.c:5:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
/tmp/cciR63og.o: In function `main':
function.c:(.text+0x19): undefined reference to `integrate'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
每当我尝试使用gcc -Wall …
根据扩展汇编程序的gcc文档:
当操作数的约束允许寄存器时,您应该只使用读写操作数.
这似乎是非常明确的:你不能使用+ m作为输出.
但是,我已经看过很多次了.事实上,Linus Torvalds有记录说
gcc文档是次要的.他们没有更新,他们不正确,他们没有反映现实,他们并不重要.对于像这样的事情,唯一正确的用法是"+ m"
如果编译器最终搞砸了我的代码,我不想使用+ m.甚至检查输出asm以确定它是否正常工作并不意味着明天当我改变一些看似无关的东西时它仍然会起作用.或者当我获得gcc的下一次更新时它仍然可以工作.
如果文档是正确的,我不能依赖于这种正常工作,我想知道,所以我可以寻求其他选择(其中大多数是令人不快的痛苦).如果文档错误,请告诉我如何纠正它们.
我正在研究一个cpp项目.该项目需要迁移到64位.它包含一些无法在x64上编译的内联汇编代码.这是包含汇编代码的函数:
void ExternalFunctionCall::callFunction(ArgType resultType, void* resultBuffer)
{
#if defined(_NT_) || defined(__OS2__)
// I386
// just copy the args buffer to the stack (it's already layed out correctly)
int* begin = m_argsBegin;
int* ptr = m_argsEnd;
int arr[1000], i=0;
while (ptr > begin) {
int val = *(--ptr);
__asm push val
}
void* functionAddress = m_functionAddress;
// call the function & handle the return value. use __stdcall calling convention
switch (resultType) {
case voidType:
__asm {
call functionAddress
}
break;
case …Run Code Online (Sandbox Code Playgroud) 我在函数中有以下代码:
void makeSystemCall(uint32_t num, uint32_t param1, uint32_t param2, uint32_t param3){
asm volatile (
"mov %0, %%eax\n\t"//Move num to eax
"mov %1, %%ebx\n\t"//Move param1 to ebx
"mov %2, %%ecx\n\t"//Move param2 to ecx
"mov %3, %%edx\n\t"//Move param3 to edx
"int $0x80"//Call interrupt. Data in eax, ebx, ecx and edx
: //No output params
: "r" (num), "r" (param1), "r" (param2), "r" (param3)//Input params
: "%eax", "%ebx", "%ecx", "%edx" //This handles register state pushing and popping?
);
}
Run Code Online (Sandbox Code Playgroud)
现在我不知道为什么这不起作用.Gcc说:"错误:'asm'操作数有不可能的约束"我一直在关注gcc内联汇编教程,我认为这是将参数从c代码转换为内联汇编块的正确方法.
我也使用为32位x86构建的gcc交叉编译器.
我在PowerPC上遭受GCC内联汇编.该程序编译良好-g2 -O3,但无法编译-g3 -O0.问题是,我需要在调试器下观察它,所以我需要没有优化的符号.
这是程序:
$ cat test.cxx
#include <altivec.h>
#undef vector
typedef __vector unsigned char uint8x16_p;
uint8x16_p VectorFastLoad8(const void* p)
{
long offset = 0;
uint8x16_p res;
__asm(" lxvd2x %x0, %1, %2 \n\t"
: "=wa" (res)
: "g" (p), "g" (offset/4), "Z" (*(const char (*)[16]) p));
return res;
}
Run Code Online (Sandbox Code Playgroud)
这是错误.(自使用内联汇编替换PowerPC vec_xl_be以来,该错误已经存在,但直到现在我才能忽略它).
$ g++ -g3 -O0 -mcpu=power8 test.cxx -c
/home/test/tmp/ccWvBTN4.s: Assembler messages:
/home/test/tmp/ccWvBTN4.s:31: Error: operand out of range (64 is not between 0 and 31) …Run Code Online (Sandbox Code Playgroud) inline-assembly ×10
assembly ×6
c++ ×6
gcc ×5
c ×4
altivec ×1
conventions ×1
icc ×1
low-level ×1
optimization ×1
powerpc ×1
visual-c++ ×1
x86 ×1
x86-64 ×1
xcode ×1