Tag: 内联汇编

如何使用内联汇编指定直接浮点数?

当我尝试编译此代码时: #include main(int argc, char *argv[]) { double y = 0; __asm__ (“fldl $150;” “fsqrt;” “fstl %0;” : : “g” (y) ); printf(“%f\n”, y); return 0; } 我收到此错误: sqrt.c: Assembler messages: sqrt.c:6: Error: suffix or operands invalid for `fld’ 为什么这不起作用? 为什么我不能将数字“150”推入堆栈进行浮点运算?

这个汇编函数调用安全/完整吗?

我没有assembly经验,但这是我一直在努力的。 如果我缺少传递参数和通过程序集中的指针调用函数的任何基本方面,我想输入。 例如,我想知道我是否应该恢复ecx , edx , esi , edi 。 我读过它们是通用寄存器,但我找不到它们是否需要恢复? 打电话后我应该做什么样的清理工作? 这是我现在的代码,它确实有效: #include “stdio.h” void foo(int a, int b, int c, int d) { printf(“values = %d and %d and %d and %d\r\n”, a, b, c, d); } int main() { int a=3,b=6,c=9,d=12; __asm__( “mov %3, %%ecx;” “mov %2, %%edx;” “mov %1, %%esi;” “mov […]

at&t asm inline c ++问题

我的代码 const int howmany = 5046; char buffer[howmany]; asm(“lea buffer,%esi”); //Get the address of buffer asm(“mov howmany,%ebx”); //Set the loop number asm(“buf_loop:”); //Lable for beginning of loop asm(“movb (%esi),%al”); //Copy buffer[x] to al asm(“inc %esi”); //Increment buffer address asm(“dec %ebx”); //Decrement loop count asm(“jnz buf_loop”); //jump to buf_loop if(ebx>0) 我的问题 我正在使用gcc编译器。 出于某种原因,我的缓冲区/ howmany变量在我的asm眼中是不确定的。 我不知道为什么。 我只想将缓冲区数组的起始地址移动到esi寄存器中,将每个元素复制到al寄存器时循环“howmany”次。

内联assembly破坏了红色区域

我正在编写一个加密程序,并且核心(一个广泛的乘法例程)是用x86-64汇编编写的,既速度又因为它广泛使用了不容易从C访问的adc指令。我不想内联这个函数,因为它很大,并且在内循环中被调用了好几次。 理想情况下,我还想为此函数定义一个自定义调用约定,因为在内部它使用所有寄存器( rsp除外),不破坏其参数,并在寄存器中返回。 现在,它适应了C调用约定,但当然这使它变慢(大约10%)。 为了避免这种情况,我可以用asm(“call %Pn” : … : my_function… : “cc”, all the registers);调用它asm(“call %Pn” : … : my_function… : “cc”, all the registers); 但有没有办法告诉GCC调用指令与堆栈混淆? 否则GCC会将所有这些寄存器放在红色区域中,而顶部的寄存器将被破坏。 我可以使用-mno-red-zone编译整个模块,但我更喜欢告诉GCC,比方说,红色区域的前8个字节将被破坏,以便它不会放任何东西。

‘asm’,’__ asm’和’__asm__’有什么区别?

据我所知, __asm { … };之间的唯一区别__asm { … }; 和__asm__(“…”); 是第一个使用mov eax, var ,第二个使用movl %0, %%eax使用:”=r” (var) 。 还有什么其他差异? 那么asm呢?

使用背靠背rdtsc进行负时钟周期测量?

我正在编写一个C代码,用于测量获取信号量所需的时钟周期数。 我正在使用rdtsc,在对信号量进行测量之前,我连续两次调用rdtsc来测量开销。 我在for循环中重复了这么多次,然后我使用平均值作为rdtsc开销。 这是正确的,首先要使用平均值吗? 尽管如此,这里的一个大问题是,有时我会得到开销的负值(不一定是平均值,但至少是for循环中的部分值)。 这也会影响sem_wait()操作所需的cpu周期数的连续计算,有时也会产生负数。 如果我写的不清楚,这里有一部分我正在编写的代码。 为什么我会得到这样的负值? (编者注:请参阅获取CPU周期计数?以获得完整的64位时间戳的正确和可移植方式。 “=A” asm约束仅在编译为x86-64时获得低或高32位,具体取决于寄存器分配是否恰好为uint64_t输出选择RAX或RDX。它不会选择edx:eax 。) (编辑的第二个注释:哎呀,这就是为什么我们得到负面结果的答案。仍然值得留下一个注释,作为警告不要复制这个rdtsc实现。) #include #include #include #include #include static inline uint64_t get_cycles() { uint64_t t; // editor’s note: “=A” is unsafe for this in x86-64 __asm volatile (“rdtsc” : “=A”(t)); return t; } int num_measures = 10; int main () { int i, value, res1, […]

使用内联汇编在数组上循环

当使用内联汇编循环数组时,我应该使用寄存器修饰符“r”还是内存修饰符“m”? 让我们考虑一个添加两个浮点数组x和y并将结果写入z的示例。 通常我会使用内在函数这样做 for(int i=0; i<n/4; i++) { __m128 x4 = _mm_load_ps(&x[4*i]); __m128 y4 = _mm_load_ps(&y[4*i]); __m128 s = _mm_add_ps(x4,y4); _mm_store_ps(&z[4*i], s); } 这是我使用寄存器修饰符“r”提出的内联汇编解决方案 void add_asm1(float *x, float *y, float *z, unsigned n) { for(int i=0; i<n; i+=4) { __asm__ __volatile__ ( "movaps (%1,%%rax,4), %%xmm0\n" "addps (%2,%%rax,4), %%xmm0\n" "movaps %%xmm0, (%0,%%rax,4)\n" : : "r" (z), […]