C 内联汇编帮助(数字 mars c 编译器)

Posted

技术标签:

【中文标题】C 内联汇编帮助(数字 mars c 编译器)【英文标题】:C inline assembly help (digital mars c compiler) 【发布时间】:2014-05-12 00:28:23 【问题描述】:

Scratch last edit...它仍然无法正常工作,据我所知,地址偏移量仍然以字节为单位>_

我正在尝试用 C 编写我自己的任意精度整数运算实现。为了有效地做到这一点,我需要使用内联汇编函数来访问进位标志,并访问高 32 位和低 32 位32bx32b 乘法的结果。

所以我写了这个函数,将两个 32 位整数 a 和 b 相乘,并将乘积的高部分存储在 c 中,低部分存储在 d 中。

void longMul(int a, int b, int *c, int *d) 
asm 
    mov EAX, a
    mul b
    mov ESI, c
    mov [ESI], EDX
    mov ESI, d
    mov [ESI], EAX

现在我从我的 BigInteger_Mul 函数中调用这个函数,其中 a 和 b 是指向整数数组的指针(这是我存储大整数的方式),而 i 和 j 是指向 a 和 b 的索引。 highPart 和 lowPart 存储相乘的结果。所以它在我的代码中看起来像这样(我省略了大部分代码,因为问题只涉及一行):

 void BigInteger_Mul( length, int *a, int *b, int *dest)      
     ... do a bunch of stuff ...
     int highPart, lowPart;
     longMul( *(a+i), *(b+j), &highPart, &lowPart);
     ... do a bunch more stuff ...

我已经对其进行了测试,并且代码完全按照我的预期工作(...对于至少一组输入:P)。现在,我试图通过将 Mul 函数完全转换为汇编、内联所有函数调用并进行优化来提高效率。

所以我的第一步是换行:

longMul( *(a+i), *(b+j), &highPart, &lowPart);

使用我认为功能等效的汇编代码:

asm 
            mov ESI, a
            mov ECX, i
            mov EAX, [ESI+ECX*4]

            mov ESI, b
            mov ECX, j
            mul [ESI+ECX*4]

            mov lowPart, EAX
            mov highPart, EDX

我得到了完全错误的结果。那么为什么第二个代码块的行为不像第一个呢?原谅我的菜鸟,我没有 x86 汇编的背景,只是决定直接跳进去。这可能也是一个愚蠢的错误。

编辑:我刚刚发现内联汇编应该保留 ESI 寄存器。即使我将它的内容存储在一个变量中,然后在最后恢复它们,它似乎也没有帮助。

【问题讨论】:

看起来不错。检查生成的程序集并使用调试器。更不用说使用现成的 bignum 库或简单地使用编译器中的双宽度支持(long longuint64_t 或其他)。 mul [ESI+ECX*4] 不明确。如果您希望内存操作数被解释为dword,您应该明确地告诉汇编器。 迈克尔,你完全正确。我需要输入 mul dword ptr。这解决了我的问题。谢谢。 @Michael,您可以添加您的评论作为答案吗?它解决了 OP 的问题,我会投票赞成。 【参考方案1】:

不知道为什么您的代码不起作用。看起来不错,但我也得到了不好的结果。 这是很长的路,但它对我有用:

asm 
  mov EAX, j
  mov EBX, 4
  mul EAX, EBX
  mov EBX, b
  add EAX, EBX
  mov ECX, EAX

  mov ESI, a
  mov EBX, i
  mov EAX, [ESI+EBX*4]

  mov ESI, ECX
  mul [ESI] 
  mov lowPart, EAX
  mov highPart, EDX
  

【讨论】:

以上是关于C 内联汇编帮助(数字 mars c 编译器)的主要内容,如果未能解决你的问题,请参考以下文章

C语言进阶——内联汇编

C语言进阶——内联汇编

C/C++ 中的简单“Hello World”内联汇编语言程序

ARM嵌入式开发中的GCC内联汇编__asm__

LLVM GCC 4.2 中内联汇编的奇怪编译

x86平台转x64平台关于内联汇编不再支持的解决