相关疑难解决方法(0)

为什么GCC在实现整数除法时使用乘以奇数的乘法?

我一直在阅读divmul组装操作,我决定通过在C中编写一个简单的程序来实现它们:

文件分割

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后生成汇编语言代码:

gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)

但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:

mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 integer-division

206
推荐指数
4
解决办法
1万
查看次数

使用位移除以10?

是否有可能通过使用纯位加法,减法除以10的无符号整数,也许繁衍?使用资源非常有限且速度慢的处理器.

math bit low-level integer-division micro-optimization

41
推荐指数
4
解决办法
5万
查看次数

有没有更有效的方法将数字分成数字?

我必须将数字拆分成数字才能在LCD上显示.现在我使用以下方法:

pos = 7;

do
{
    LCD_Display(pos, val % 10);
    val /= 10;
    pos--;
} while (pos >= 0 && val);
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于MSP430微控制器上的除法和模运算非常慢.有没有替代这种方法的东西,既不涉及分裂,也不会减少操作次数?

注意:我不能使用任何库函数,例如itoa.这些库很大,而且功能本身也非常耗费资源(在循环次数和RAM使用方面).

c performance digits

15
推荐指数
2
解决办法
1522
查看次数

GCC/ARM快速部门

据我所知,大多数编译器会通过乘法然后向右移位进行快速除法.例如,如果你检查这个SO线程,它会说当你要求Microsoft编译器除以10时,它会将被除数乘以0x1999999A(即2 ^ 32/10),然后将结果除以2 ^ 32(使用32向右移动).

到现在为止还挺好.

但是,一旦我使用GCC在ARM上测试了相同的除法,但编译器做了一些略微不同的事情.首先,它将被除数乘以0x66666667(2 ^ 34/10),然后将结果除以2 ^ 34.到目前为止,除了使用更高的乘数之外,它与Microsoft相同.然而,在那之后,它从结果中减去(被除数/ 2 ^ 31).

我的问题:为什么在ARM版本上有额外的减法?你能给我一个数字例子,如果没有减法,结果会出错吗?

如果你想检查生成的代码,它在下面(带我的评论):

        ldr     r2, [r7, #4] @--this loads the dividend from memory into r2
        movw    r3, #:lower16:1717986919 @--moves the lower 16 bits of the constant 
        movt    r3, #:upper16:1717986919 @--moves the upper 16 bits of the constant
        smull   r1, r3, r3, r2 @--multiply long, put lower 32 bits in r1, higher 32 in r3
        asr     r1, r3, #2 @--r3>>2, then store in r1 (effectively …
Run Code Online (Sandbox Code Playgroud)

assembly gcc arm integer-division

10
推荐指数
2
解决办法
3495
查看次数

不使用%和/运算符的5的可分性

如何在不使用%和/运算符的情况下检查数字是否可被5整除. 我想要一个最快的算法来解决这个问题.

c algorithm

4
推荐指数
2
解决办法
2708
查看次数