Tag: 程序集

关于在C / C ++ / Assembly中返回多个值

我已经阅读了一些关于返回多个值的问题,例如在C ++和Java中只有一个返回值的原因是什么? , 从C ++函数和https://softwareengineering.stackexchange.com/questions/203471/why-do-most-programming-languages-only-support-returning-a-single-value-from-af 返回多个值 。 我同意用于certificate多个返回值不是绝对必要的大多数参数,我理解为什么没有实现这样的function,但我仍然无法理解为什么我们不能使用多个调用者保存的寄存器例如ECX和EDX返回这样的值。 使用寄存器而不是创建一个Class / Struct来存储这些值或通过引用/指针传递参数不是更快,两者都使用内存来存储它们吗? 如果可以做这样的事情,那么任何C / C ++编译器是否都使用此function来加速代码? 编辑:理想的代码是这样的: (int, int) getTwoValues(void) { return 1, 2; } int main(int argc, char** argv) { (int a, int b) = getTwoValues();//a and b are actually returned in registers so future operations with a and b are faster //do something with […]

在C / C ++中使用内联汇编

我正在尝试使用内联汇编…我读过这个页面http://www.codeproject.com/KB/cpp/edujini_inline_asm.aspx但我无法理解传递给我的函数的参数。 我正在写一个C写的例子..这是我的函数头: write2(char *str, int len){ } 这是我的汇编代码: global write2 write2: push ebp mov ebp, esp mov eax, 4 ;sys_write mov ebx, 1 ;stdout mov ecx, [ebp+8] ;string pointer mov edx, [ebp+12] ;string size int 0x80 ;syscall leave ret 我该怎么做才能将代码传递给C函数…我正在做这样的事情: write2(char *str, int len){ asm ( “movl 4, %%eax;” “movl 1, %%ebx;” “mov %1, %%ecx;” […]

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

我没有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 […]

使用C / Intel程序集,测试128字节内存块是否包含全零的最快方法是什么?

继续我的第一个问题,我正在尝试优化通过VTune分析64位C程序找到的内存热点。 特别是,我想找到一种最快的方法来测试一个128字节的内存块是否包含全零。 您可以假设内存块有任何所需的内存对齐方式; 我使用64字节对齐。 我使用的是配备Intel Ivy Bridge Core i7 3770处理器和32 GB内存的PC以及免费版的Microsoft vs2010 C编译器。 我的第一次尝试是: const char* bytevecM; // 4 GB block of memory, 64-byte aligned size_t* psz; // size_t is 64-bits // … // “m7 & 0xffffff80” selects the 128 byte block to test for all zeros psz = (size_t*)&bytevecM[(unsigned int)m7 & 0xffffff80]; if (psz[0] […]

理解空main()的转换为汇编

有人可以解释GCC正在为这段代码做些什么吗? 什么是初始化? 原始代码是: #include int main() { } 它被翻译成: .file “test1.c” .def ___main; .scl 2; .type 32; .endef .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax […]

根据AMD64 ABI,什么样的C11数据类型是arrays

我正在研究在OSX上使用的x86_64的调用约定,并且在System V x86-64 ABI标准中阅读了名为“Aggregates and Unions”的部分。 它提到了数组,我认为这就像一个固定长度的c数组,例如int[5] 。 我下到“3.2.3参数传递”来读取数组是如何传递的,如果我理解正确的话,像uint8_t[3]这样的东西应该在寄存器中传递,因为它小于规则1规定的4个8字节的限制。聚合类型的分类(第18页靠近底部)。 编译后,我看到它被作为指针传递。 (我正在使用OSX 10.11.6上的Xcode 7.3.1中的clang-703.0.31进行编译)。 我用来编译的示例源如下: #include #define type char extern void doit(const type[3]); extern void doitt(const type[5]); extern void doittt(const type[16]); extern void doitttt(const type[32]); extern void doittttt(const type[40]); int main(int argc, const char *argv[]) { const char a[3] = { 1, 2, 3 }; const […]

什么是在x86上提供无分支FP min和max的指令?

引用(感谢作者开发和共享算法!): Fast, Branchless Ray/Bounding Box Intersections 由于现代浮点指令集可以在没有分支的情况下计算最小值和最大值 作者的相应代码就是 dmnsn_min(double a, double b) { return a < b ? a : b; } 我熟悉例如_mm_max_ps ,但这是一个向量指令。 上面的代码显然是用于标量forms。 题: 什么是x86上的标量无分支minmax指令? 这是一系列指令吗? 假设它将被应用,或者如何调用它是否安全? 关于min / max的无分支问题是否有意义? 根据我的理解,对于光线跟踪器和/或其他视觉软件,给定光线盒交叉例程,分支预测器没有可靠的模式来拾取,因此消除分支确实有意义。 我是对的吗? 最重要的是,所讨论的算法是围绕(+/-)INFINITY进行比较而建立的。 这是可靠的,我们正在讨论的(未知)指令和浮点标准吗? 以防万一:我熟悉在C ++中使用min和max函数 ,相信它是相关的,但不是我的问题。

如何从独立环境中关闭计算机电源?

我正在制作一个基于英特尔x86架构的保护模式操作系统,并且正在寻找有关如何通过汇编代码关闭计算机电源的一些信息。 你能帮我解决这个问题吗?

在不是地址/指针的值上使用LEA?

我试图理解地址计算指令是如何工作的,特别是使用leaq命令。 当我看到使用leaq进行算术运算的例子时,我感到困惑。 例如,以下C代码, long m12(long x) { return x*12; } 在组装中, leaq (%rdi, %rdi, 2), %rax salq $2, $rax 如果我的理解是正确的,leaq应该移动任何地址(%rdi, %rdi, 2) ,这应该是2*%rdi+%rdi ,评估为%rax 。 我感到困惑的是因为值x存储在%rdi ,这只是存储器地址,为什么%rdi乘以3然后左移这个存储器地址 2等于x乘以12? 是不是当我们将%rdi乘以3时,我们跳转到另一个不保持值x的内存地址?

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

当使用内联汇编循环数组时,我应该使用寄存器修饰符“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), […]