2016-12-07 66 views
1

我正在做的事情,將不使用MUL或DIV運算符在組件中分兩個數字。邏輯是,如果n * var < x,其中x是要除的數字,var是除以的數字,則n加1並重復。因此,如果有餘數,分頻器會將答案加1。如何在不使用MUL或DIV運算符的情況下將兩個數字在程序集中分開?

首先,我創建了一個利用位移的乘法器,並且這可以工作。

//multiply 
int ans, var1; 
_asm { 
     mov eax, 00001111b; A = 1111 
     mov ebx, 00001010b; B = 1010 
     mov var1, 00000001b; C = 0001 
     mov ecx, 0; 
     shl ebx, 3; shift b register left by 3 
    L1: 
     cmp ecx, 4; check if multiplication is done 
      je L4; go to empty loop 
     inc ecx; increment counter by 1 
     AND var1, eax; check if the least significant bit is 1 
     cmp var1, 1; checks if var1 is = 1 
      je L2; 
     cmp var1, 0; check if var1 = 0 
      je L3; 
    L2: 
     shr eax, 1; shift a register right 1 bit 
     add eax, ebx; add a and b registers 
     jmp L1; go back to L1 
    L3: 
     shr eax, 1; 
     jmp L1; go back to L1 
    L4 : 
     mov ans, eax; move eax to answer 
}; 
cout << "Multiply 00001111 and 00001010" << endl << ans << endl; 

所以我試圖做的就是實現這個乘數兩個循環:即檢查如果n VAR> = X一個N遞增,並設置寄存器以正確的數量倍增,和一個。如果n是 var < x,它將增加n並設置寄存器乘,然後將它們相乘。找到答案後,遞增的寄存器(edx)只是變量d並輸出到控制檯。

這個程序有些問題我沒有看到,不知何故,答案總是變成var2 * 16,其中var2是要分割的數字。

int var1; 
int var2; 
int var3; 
int d; 
_asm { 
    ; if n*var3 < var2, increment n and repeat 
    mov var2, 12; number to be divided 
    mov var3, 5; number to divide with 
    mov ecx, 0; 
    mov edx, 0; number to increment 
L11 : 
    cmp eax, var2; 
    js L12; if n*n < var2, increment n and multiply. 
    cmp eax, var2 
    jns L16; answer found, jump to empty loop  
L12 : 
    inc edx 
    mov eax, edx 
    mov ebx, var3 
    shl ebx, 3 
    mov ecx, 0 
    jmp L13 
L13 : 
    cmp ecx, 4; check if multiplication is done 
    je L11; 
    inc ecx; increment counter by 1 
    AND var1, eax; check if the least significant bit is 1 
    cmp var1, 1; checks if var1 is = 1 
    je L14; 
    cmp var1, 0; check if var1 = 0 
    je L15; 
L14: 
    shr eax, 1; shift a register right 1 bit 
    add eax, ebx; add a and b registers 
    jmp L13; go back to L1 
L15 : 
    shr eax, 1; 
    jmp L13; 
L16: 
    mov d, edx 
}; 
cout << "The quotient is " << d << endl; 

我也創造了非常相似的程序,計算一個數的平方根,其中,如果N * N < x,其中x是採取的,增量的平方根n和重複次數。用分隔線解決這個錯誤也應該可以幫助我處理髮生相同錯誤的平方根程序。

我一直堅持這幾天,我無法弄清楚是什麼錯誤導致這個奇怪的錯誤。任何幫助表示讚賞。

+4

使用調試器來遍歷代碼,看看它沒有做到你想做的。 – Jester

+0

前一段時間,我用普通的asm編碼了一個小波蘭註釋計算器。它的工作,至少對於整數。儘管如此,整數分解的結果也是小數,這似乎也起作用。只要你知道,這個劃分是重複的減法,你可以通過使用sub來完成。我是這樣做的。 – icbytes

+1

在第二個代碼塊中:第一次運行'L11:'時,'eax'是什麼?看起來沒有定義給我。加上'js/jns'做兩次'cmp'會浪費CPU週期。在第一個'cmp + js'指令對之後,你不需要再次執行'cmp',因爲標誌仍然是從前一個設置的(然後'js'不會修改標誌),並且'jns'會在100%因爲所有的SF = 1例已經被前面的'js'拾取。 ......我只檢查了第二塊的〜10行,因爲我很好奇你是否真的*做過++ n,然後再乘以'n * var' AGAIN,OMG:D ..可笑。 '(n + 1)* var ==(n * var)+ var'! – Ped7g

回答

0

減量可以回答你的問題(「我怎樣劃分在裝配兩個號碼不使用乘除運算符?」),例如(在VS2013測試):

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

int main(void){ 
    int dividend; 
    cout << "Enter DIVIDEND : "; //◄■ EXAMPLE : 23. 
    cin >> dividend; 

    int divisor; 
    cout << "Enter DIVISOR : "; //◄■ EXAMPLE : 4. 
    cin >> divisor; 

    int quotient = 0; 
    _asm { 
      mov eax, dividend 
     divisions: 
      cmp eax, divisor 
      jb finish  //◄■ IF DIVIDEND < DIVISOR 
      sub eax, divisor //◄■ DIVIDEND - DIVISOR. EXAMPLE : 23 - 4. 
      inc quotient  //◄■ DIVISIONS COUNTER. 
      jmp divisions 
     finish: 
    } 
    cout << "The result is " << quotient; //◄■ EXAMPLE : 5 
    return 0; 
} 

前面的代碼會拋出整數結果。如果你想得到小數的結果,有必要將最後一個被除數(前面的例子中的3)乘以10得到一位小數,或者乘以100得到兩位小數(或者對於三位小數,等等),例如(在VS2013上測試) ):

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

int main(void){ 
    int dividend; 
    cout << "Enter DIVIDEND : "; //◄■ EXAMPLE : 23. 
    cin >> dividend; 

    int divisor; 
    cout << "Enter DIVISOR : "; //◄■ EXAMPLE : 4. 
    cin >> divisor; 

// ▼ CALCULATE QUOTIENT. 
    int quotient = 0; 
    _asm { 
      mov eax, dividend 
     divisions: 
      cmp eax, divisor 
      jb finish1  //◄■ IF DIVIDEND < DIVISOR 
      sub eax, divisor //◄■ DIVIDEND - DIVISOR. EXAMPLE : 23 - 4. 
      inc quotient  //◄■ DIVISIONS COUNTER. 
      jmp divisions 
     finish1: 
      mov dividend, eax //◄■ LAST DIVIDEND (USED FOR REMAINDER). EXAMPLE : 3. 
    } 

// ▼ CALCULATE REMAINDER WITH TWO DECIMALS. 
    int remainder = 0; 
    _asm { 
     // ▼ MULTIPLY LAST DIVIDEND BY 100. EXAMPLE : 3 * 100 = 300. 
      mov ecx, 100 //◄■ REPEAT 100 TIMES. 
      mov eax, 0 
     multiply: 
      add eax, dividend //◄■ MULTIPLY IS A SERIES OF ADDITIONS. EXAMPLE : EAX + 3. 
      loop multiply 
     // ▼ GET REMAINDER WITH TWO DECIMALS. 
     decimals: 
      cmp eax, divisor 
      jb finish2 //◄■ IF DIVIDEND < DIVISOR 
      sub eax, divisor //◄■ DIVIDEND - DIVISOR. EXAMPLE : 300 - 4. 
      inc remainder //◄■ DIVISIONS COUNTER. 
      jmp decimals 
     finish2: 
    } 
    cout << "The result is " << quotient << "." << remainder; //◄■ EXAMPLE : 5.75 
    return 0; 
} 
相關問題