2016-12-07 67 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; 
} 
相关问题