您的位置:首页 > 其它

有符号数除以非2的幂

2016-09-10 18:24 127 查看

前言





当x为有符号数时, 此公式适用.

此公式推导的前提是 x < 0.

看着公式,再对着反汇编代码看,感觉不一样,不用硬背了.

随着编译器生成的c不同,有可能n就是32, 不再需要右移了.

但是最后的-x+1的动作还是有的(x > 0时, 等于 + 0, 和无符号除以非2的幂相同了).

试验

// hw.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>

void fnIdiv3(int x) {
printf("==========\r\n");
printf("%d\r\n", x/3);
}

void fnIdiv5(int x) {
printf("==========\r\n");
printf("%d\r\n", x/5);
}

void fnIdiv6(int x) {
printf("==========\r\n");
printf("%d\r\n", x/6);
}

void fnIdiv9(int x) {
printf("==========\r\n");
printf("%d\r\n", x/9);
}

int main(int argc, char* argv[])
{
// hw1_5 验证 : 有符号数除以非2的幂(MagicNumber为正)
fnIdiv3(6);
fnIdiv5(15);
fnIdiv6(24);
fnIdiv9(45);

fnIdiv3(-6);
fnIdiv5(-15);
fnIdiv6(-24);
fnIdiv9(-45);

/** run result
==========
2
==========
3
==========
4
==========
5
==========
-2
==========
-3
==========
-4
==========
-5
请按任意键继续. . .
*/

system("pause");
return 0;
}


.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000
.text:00401000 fniDiv3         proc near               ; CODE XREF: _main+2p
.text:00401000                                         ; _main+1Ep
.text:00401000
.text:00401000 arg_0           = dword ptr  4
.text:00401000
.text:00401000                 push    offset Format   ; "==========\r\n"
.text:00401005                 call    _printf
.text:0040100A                 mov     ecx, [esp+4+arg_0] ; step1
.text:0040100E                 mov     eax, 55555556h  ; step2
.text:00401013                 imul    ecx             ; step3
.text:00401015                 mov     eax, edx        ; step4
.text:00401017                 add     esp, 4
.text:0040101A                 shr     eax, 1Fh        ; step5
.text:0040101D                 add     edx, eax        ; step6
.text:0040101F                 push    edx
.text:00401020                 push    offset aD       ; "%d\r\n"
.text:00401025                 call    _printf
.text:0040102A                 add     esp, 8
.text:0040102D                 retn
.text:0040102D fniDiv3         endp
.text:0040102D
.text:0040102D ; ---------------------------------------------------------------------------
.text:0040102E                 align 10h
.text:00401030
.text:00401030 ; =============== S U B R O U T I N E =======================================
.text:00401030
.text:00401030
.text:00401030 fniDiv5         proc near               ; CODE XREF: _main+9p
.text:00401030                                         ; _main+25p
.text:00401030
.text:00401030 arg_0           = dword ptr  4
.text:00401030
.text:00401030                 push    offset Format   ; "==========\r\n"
.text:00401035                 call    _printf
.text:0040103A                 mov     ecx, [esp+4+arg_0] ; step1
.text:0040103E                 mov     eax, 66666667h  ; step2
.text:00401043                 imul    ecx             ; step3
.text:00401045                 sar     edx, 1          ; step4
.text:00401047                 mov     eax, edx        ; step5
.text:00401049                 add     esp, 4
.text:0040104C                 shr     eax, 1Fh        ; step6
.text:0040104F                 add     edx, eax        ; step7
.text:00401051                 push    edx
.text:00401052                 push    offset aD       ; "%d\r\n"
.text:00401057                 call    _printf
.text:0040105C                 add     esp, 8
.text:0040105F                 retn
.text:0040105F fniDiv5         endp
.text:0040105F
.text:00401060
.text:00401060 ; =============== S U B R O U T I N E =======================================
.text:00401060
.text:00401060
.text:00401060 fniDiv6         proc near               ; CODE XREF: _main+10p
.text:00401060                                         ; _main+2Cp
.text:00401060
.text:00401060 arg_0           = dword ptr  4
.text:00401060
.text:00401060                 push    offset Format   ; "==========\r\n"
.text:00401065                 call    _printf
.text:0040106A                 mov     ecx, [esp+4+arg_0] ; step1
.text:0040106E                 mov     eax, 2AAAAAABh  ; step2
.text:00401073                 imul    ecx             ; step3
.text:00401075                 mov     eax, edx        ; step4
.text:00401077                 add     esp, 4
.text:0040107A                 shr     eax, 1Fh        ; step5
.text:0040107D                 add     edx, eax        ; step6
.text:0040107F                 push    edx
.text:00401080                 push    offset aD       ; "%d\r\n"
.text:00401085                 call    _printf
.text:0040108A                 add     esp, 8
.text:0040108D                 retn
.text:0040108D fniDiv6         endp
.text:0040108D
.text:0040108D ; ---------------------------------------------------------------------------
.text:0040108E                 align 10h
.text:00401090
.text:00401090 ; =============== S U B R O U T I N E =======================================
.text:00401090
.text:00401090
.text:00401090 fniDiv9         proc near               ; CODE XREF: _main+17p
.text:00401090                                         ; _main+33p
.text:00401090
.text:00401090 arg_0           = dword ptr  4
.text:00401090
.text:00401090                 push    offset Format   ; "==========\r\n"
.text:00401095                 call    _printf
.text:0040109A                 mov     ecx, [esp+4+arg_0] ; step1
.text:0040109E                 mov     eax, 38E38E39h  ; step2
.text:004010A3                 imul    ecx             ; step3
.text:004010A5                 sar     edx, 1          ; step4
.text:004010A7                 mov     eax, edx        ; step5
.text:004010A9                 add     esp, 4
.text:004010AC                 shr     eax, 1Fh        ; step6
.text:004010AF                 add     edx, eax        ; step7
.text:004010B1                 push    edx
.text:004010B2                 push    offset aD       ; "%d\r\n"
.text:004010B7                 call    _printf
.text:004010BC                 add     esp, 8
.text:004010BF                 retn
.text:004010BF fniDiv9         endp
.text:004010BF
.text:004010C0
.text:004010C0 ; =============== S U B R O U T I N E =======================================
.text:004010C0
.text:004010C0
.text:004010C0 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:004010C0 _main           proc near               ; CODE XREF: start+AFp
.text:004010C0                 push    6
.text:004010C2                 call    fniDiv3
.text:004010C7                 push    15
.text:004010C9                 call    fniDiv5
.text:004010CE                 push    24
.text:004010D0                 call    fniDiv6
.text:004010D5                 push    45
.text:004010D7                 call    fniDiv9
.text:004010DC                 push    -6
.text:004010DE                 call    fniDiv3
.text:004010E3                 push    -15
.text:004010E5                 call    fniDiv5
.text:004010EA                 push    -24
.text:004010EC                 call    fniDiv6
.text:004010F1                 push    -45
.text:004010F3                 call    fniDiv9
.text:004010F8                 push    offset aPause   ; "pause"
.text:004010FD                 call    _my_system
.text:00401102                 add     esp, 24h
.text:00401105                 xor     eax, eax
.text:00401107                 retn
.text:00401107 _main           endp
.text:00401107
.text:00401107 ; ---------------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: