所以我必須將'a'乘以'b'倍,我試著這樣做。我還從我發現的其他問題中提取了一些程式。
.MODEL SMALL
.DATA
a db 3, 4 dup (0)
b db 3, 4 dup (0) ;With the buffer that this provides, this now will allow you to input from the keyboard two double-digit numbers.
.CODE
mov ax, @data ;INITIALIZE DATA SEGMENT.
mov ds, ax
START:
;a
mov ah, 0ah
mov dx, offset a
int 21h
call string2number1 ;convert a to number (a->bx)
mov dx,bx ;(a->ax)
;b
mov ah, 0ah
mov dx, offset b
int 21h
call string2number2 ;convert b to number (b->bx)
;multiplication
mov cx,bx ;b->cx (multiply by cx(b) times)
mov bx,dx ;a->bx (to do a*a)
power:
mul bx
loop power
;dx:ax should now contain m^n (i hope)
;displaying dx:ax
mov bx,10 ;CONST
push bx ;Sentinel
.a: mov cx,ax ;Temporarily store LowDividend in CX
mov ax,dx ;First divide the HighDividend
xor dx,dx ;Setup for division DX:AX / BX
div bx ; -> AX is HighQuotient, Remainder is re-used
xchg ax,cx ;Temporarily move it to CX restoring LowDividend
div bx ; -> AX is LowQuotient, Remainder DX=[0,9]
push dx ;(1) Save remainder for now
mov dx,cx ;Build true 32-bit quotient in DX:AX
or cx,ax ;Is the true 32-bit quotient zero?
jnz .a ;No, use as next dividend
pop dx ;(1a) First pop (Is digit for sure)
.b: add dl,"0" ;Turn into character [0,9] -> ["0","9"]
mov ah,02h ;DOS.DisplayCharacter
int 21h ; -> AL
pop dx ;(1b) All remaining pops
cmp dx,bx ;Was it the sentinel?
jb .b ;Not yet
;-----------------------------------------
jmp skipProcedures
;CONVERT a TO NUMBER IN BX.
proc string2number1
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
mov si, offset a 1
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx,ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp
;CONVERT b TO NUMBER IN BX.
proc string2number2
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
mov si, offset b 1
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat2:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx,ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat2 ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp
skipProcedures:
;---------------------------------------
mov ax,4c00h
int 21h
end start
在我為“a”撰寫輸入后,程式不會讓我按 Enter。當我進行乘法回圈或嘗試顯示 dx:??ax 時,也許我錯了,但這與讓我為 a 寫輸入有什么關系?我試圖在評論中盡可能多地解釋。我該怎么辦?
uj5u.com熱心網友回復:
我不斷收到與“第 18 行和第 19 行的運算元型別不匹配”相同的錯誤
這是因為 TASM 知道a和b變數是位元組大小的,因為它們是使用DB指令定義的,但是您的指令mov bx,a和mov cx,b是字大小的操作。所以,錯配。
這就是代碼中發生的事情
您的程式通過 DOS.BufferedInput 函式 0Ah使用a和b “變數”進行用戶輸入。在此處閱讀有關此功能的所有資訊。
您的定義應如下所示:
.DATA
a db 3, 4 dup (0)
b db 3, 4 dup (0)
使用它提供的緩沖區,現在這將允許您從鍵盤輸入兩個兩位數。
要真正開始使用這些數字進行計算,您需要將文本字符(輸入它們的依據)轉換為 [0,99] 范圍內的簡單數字。
下一個代碼為兩位數 a輸入完成此操作:
mov bx, offset a
mov ah, [bx 2] ; The tens ["0","9"]
mov al, [bx 3] ; The ones ["0","9"]
sub ax, "00" ; Converting to [0,9] on both at the same time
aad ; Combining both: AX = (AH * 10) AL
mov ax,0 ; Initial result, i.e. m^0 power: jcxz power_done mul bx loop power power_done:
無論您乘以 ( BX) 的值,這個乘法總是會產生零。那是因為你初始化了AX=0. 這不對應于注釋“初始結果,即 m^0”。記住這一點m^0 = 1。
您正在嘗試使用單個字符輸出函式顯示結果。這永遠都不夠!有關正確方法,請參閱此 Q/A。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/415421.html
標籤:
上一篇:Windows上的GNU匯編器:WriteFile回傳ERROR_INVALID_HANDLE
下一篇:聯結器插入不必要的操作碼填充
