2013-04-10 83 views
1

我已经编写了一半的程序。问题是我不知道如何编码数学运算部分是提高m的功率为n (m^n)。那么,作为初学者的任何建议?汇编程序(TASM)计算提升m到n的功率(m^n)

.MODEL SMALL 

.DATA 

greet db 13,10, "Welcome to Simple Calculator: Raise m to the power n. $" 
msg1 db 13,10, 0AH,0DH,"Please enter integer (m:-99 to 99): $" 
m  db 3,4 dup(?) 
msg2 db 10,13, 0AH,0DH,"Please enter power (n:1 to 9): $" 
n  db 3,4 dup(?) 
total db 10,13, "Answer: $" 


.CODE 

START: 

mov ax, seg greet 
mov ds, ax 
mov dx, offset greet 
mov ah, 09h  ;Display message 
int 21h 

mov ax, seg msg1 
mov ds, ax 
mov dx, offset msg1 
mov ah, 09h 
int 21h   ;Print a message 

mov ah, 0ah 
mov dx, offset m 
int 21h   ;Get 'm' value 


n_POWER: 

mov ax, seg msg2 
mov ds, ax 
mov dx, offset msg2 
mov ah, 09h 
int 21h   ;Print a message 

mov ah, 0ah 
mov dx, offset n ;Get 'n' value 
int 21h 

mov ax, m 
mov n, ax 
mul ax, n 
mov total, n 

finish: 
mov ah, 09h ;Display message 
int 21h 

mov ax,4c00h ;Return control to DOS 
int 21h   
end start 

另外,我如何从用户(例如,-99)获得的负输入?

+0

我需要使用“JMP”命令吗? – user2264387 2013-04-10 04:08:32

回答

1

您可以重复乘法,如:

int result = 1; while (exp-->0) { result *= base; } return result; 

或者,你可以/应该把指数在它的二进制表示:

5^13 = 5^(0b1101) = 1*(5^1)*(5^4)*(5^8) 

人们可以这样反复广场副本的基数5:5→25→625→390625,然后乘以那些在指数的二进制表示中设置了相应位的术语。

这可能是矫枉过正的16位运算,但如果你的教授要求你进行模块化求幂代替(如非对称加密使用)这将是得心应手。

两种方法都需要使用条件跳跃:

有条件地重复操作的一个简单的做的cx数:

  mov cx, 13 
label: nop // put your block of code here 
     nop 
     loop label; // The instruction at label will be executed 13 times 
     // and cx will end up being zero 

要测试一个比特被设置,一个可以做

  mov dx, 13  ;; let's have the exponent here 
label: test dx, 1  ;; check if the first bit is zero 
         ;; test performs bitwise _and_ between the operand 
         ;; and sets ZERO flag (among other things) 
     jz notset  
     nop    ;; insert here the statements to be executed 
         ;; when the bit in the exponent is set 
notset: shr dx, 1  ;; shift out the least significant bit -- this also 
         ;; sets the ZERO_FLAG if dx goes to zero 
         ;; (and it eventually does) 
     jne label;  ;; 

btw。 JNE ==如果不等于则跳转也测试零标志。 如果不为零则跳转是同义词。

+0

是的,谢谢你的帮助。但是,为什么我必须使用循环13次? '13'可以被'n'替代吗? – user2264387 2013-04-10 08:42:32

+1

是的,你可以并应该用你的变量替换常量。你也应该填写执行乘法和平方的指令。这绝不是一个完整的代码块被复制粘贴,因为这会破坏学习的目的。 – 2013-04-10 09:07:59

+0

如果我想为例如输入。 '-99',我该怎么办?我必须转换那些二进制文件?或者其他方式? – user2264387 2013-04-10 10:17:31

0

计算整数幂只是一系列乘法运算。例如,5^2 == 5 * 5,2^3 == 2 * 2 * 2等等。

因此,一个简单的乘法循环就足够了:

mov bx,5 ; m 
mov cx,3 ; n 
mov ax,1 ; Initial result, i.e. m^0 
power: 
    jcxz power_done 
    mul bx 
    loop power 
power_done: 
; ax now contains m^n 

注意,如果结果增长大于16位(除了隐含在最后一次迭代)我的示例代码不处理的情况。它也不处理m的负值。如果您需要它们,我将把它作为一个练习,让您查找指令集参考,了解如何解决这些问题。

+0

为什么你需要jcxz(如果它是通用的情况下,为什么它的循环块内?) – 2013-04-10 06:26:48

+0

为了处理所有输入一个自包含的循环块> = 0的问题是不是最快的方法计算能力(在这种情况下,OP应该使用现代C/C++编译器,并称它为一天)。 – Michael 2013-04-10 06:34:34

+0

的意思是,我可以用'm'替代常量'5'? – user2264387 2013-04-10 07:21:19