【发布时间】:2012-09-23 19:28:06
【问题描述】:
我想使用循环打印前 20 个数字。
打印前九个数字绝对没问题,因为十六进制和十进制代码是相同的,但是从第 10 个数字开始,我必须将每个数字转换为相应的代码,然后将其转换并存储为字符串并最终显示它
也就是说,
If (NUMBER > 9)
ADD 6D
;10d = 0ah --(+6)--> 16d = 10h
IF NUMBER IS > 19
ADD 12D
;20d = 14h --(+12)--> 32d = 20h
然后对每个数字进行旋转移位,得到想要的输出数字,即
DAA # let al = 74h = 0111.0100
XOR AH,AH # ah = 0 (Just in case it wasn't)
# ax = 0000.0000.0111.0100
ROR AX,4 # ax = 0100.0000.0000.0111 = 4007h
SHR AH,4 # ax = 0000.0100.0000.0111 = 0407h
ADD AX,3030h # ax = 0011.0100.0011.0111 = 3437h = ASCII "74" (Reversed due to little endian)
然后将结果存入字符串并显示出来,即
MOV BX,OFFSET Result ;Let Result is an empty string
MOV byte ptr[BX],5 ;Size of the string
MOV byte ptr[BX+4],'$' ;String terminator
MOV byte ptr[BX+3],AH ;storing number
MOV byte ptr[BX+2],AL
MOV DX,BX
ADD DX,02 ;Displaying the result
MOV AH,09H ;Interrupt 21 service to display string
INT 21H
这是带有适当注释的完整代码,
MOV CX,20 ;Number of iterations
MOV DX,0 ;First value of the sequence
L1:
PUSH DX
ADD DX,30H ; 30H is equal to 0 in hexadecimal , 31H = 1 and so on
MOV AH,02H ; INTERRUPT Service to print the DX content
INT 21H
POP DX
ADD DX,1
CMP DX,09 ; if number is > 9 i.e 0A then go to L2
JA L2
LOOP L1
L2:
PUSH DX
MOV AX,DX
CMP AX,14H ;If number is equal to 14H(20) then Jump to L3
JE L3
ADD AX,6D ;If less than 20 then add 6D
XOR AH,AH ;Clear the content of AH
ROR AX,4 ;Rotating and Shifting for to properly store
SHR AH,4
ADC AX,3030h
MOV BX,OFFSET Result
MOV byte ptr[BX],5
MOV byte ptr[BX+4],'$'
MOV byte ptr[BX+3],AH
MOV byte ptr[BX+2],AL
MOV DX,BX
ADD DX,02
MOV AH,09H
INT 21H
POP DX
ADD DX,1
LOOP L2
;If the number is equal to 20 come here, ->
; Every step is repeated here just to change 6D to 12D
L3:
ADD AX,12D
XOR AH,AH
ROR AX,1
ROR AX,1
ROR AX,1
ROR AX,1
SHR AH,1
SHR AH,1
SHR AH,1
SHR AH,1
ADC AX,3030h
MOV BX,OFFSET Result
MOV byte ptr[BX],5
MOV byte ptr[BX+4],'$'
MOV byte ptr[BX+3],AH
MOV byte ptr[BX+2],AL
MOV DX,BX
ADD DX,02
MOV AH,09H
INT 21H
有什么合适的方法可以做到这一点,创建一个函数并使用 if/else(跳转)来获得所需的输出,而不是一次又一次地重复代码?
伪代码:
VAR = 6
IF Number is > 9
ADD AX,VAR
Else IF Number is > 19
ADD AX,(VAR*2)
ELSE IF NUMBER is > 29
ADD AX,(VAR*3)
【问题讨论】:
-
IF/ELSE 直接转换为 CMP/Jcc/JMP。我不确定您是如何到达
30H is equal to 1 in hexadecimal的。此外,函数 2 不需要字符串的长度,它会打印所有内容,直到到达 "$"。 -
抱歉写错了 (30h = 0) ,你能给我一个两行代码示例我们如何使用 CMP/JCC/JMP 吗?或者创建一个函数,我只是要求一个例子
-
所有
IF COND A ELSE B所做的只是执行一段代码(A,如果COND为真)或另一段代码(B,如果COND为假)。所以你用CMP检查条件。然后使用适当的Jcc直接在IF(A) 之后或ELSE(B) 之后立即执行代码。不用说,A不应该以在B中继续执行而结束,它必须跳过B。你有一个或两个,而不是两者。 -
我真的认为你会更喜欢“aam”而不是“daa”(除非它是“作业”的一部分)。我怀疑你是否想要“adc”,除非你真的想添加进位标志 - 使用普通的“add”。请注意,一个字节可能是三位数字,此代码仅适用于两位!适用于“最多 20 个”......也适用于“时间”数字。 (否则重复使用“div”...)
标签: function assembly x86 tasm