繁体   English   中英

TASM程序采用3位输入,从输入中减去一个数字,然后输出结果

[英]TASM program to take 3-digit input, subtract a number from the input, and output the result

这是我用TASM编写的程序:

dosseg
.model small
.stack 100h
.data
h1 db 0
t1 db 0
o1 db 0
n db 0
hc db 0
tc db 0
prompt db 'Input 3 digit number: $'
prompt2 db 'Result: $'
lf db 0Dh,0Ah,24h

.code
mov ax,@data
mov ds,ax

lea dx,prompt
mov ah,09h
int 21h

mov ah,01h
int 21h
sub al,30h
mov h1,al

int 21h
sub al,30h
mov t1,al

int 21h
sub al,30h
mov o1,al

cmp h1,00h
jg hn
add n,00h

o:
mov bl,o1
add n,bl
jmp t

hn:
add n,64h
dec h1,01h
cmp h1,00h
jne hn

t:
cmp t1,00h
jg tn
add n,00h
jmp d

tn:
add n,0Ah
dec t1,01h
cmp t1,00h
jg tn
jmp o

d:
sub n,14h
cmp n,64h
jge d2
mov hc,00h

da:
cmp n,0Ah
jge d3
mov tc,00h
jmp dsp

d2:
sub n,64h
add hc,01h
cmp n,64h
jge d2
jmp da

d3:
sub n,0Ah
add tc,01h
cmp n,0Ah
jge d3

dsp:
add hc,30h
add tc,30h
add n,30h

lea dx,lf
mov ah,09h
int 21h

lea dx,prompt2
mov ah,09h
int 21h




mov dl,hc
mov ah,02h
int 21h







mov dl,tc
mov ah,02h
int 21h


mov dl,n
mov ah,02h
int 21h

mov ah,4Ch
int 21h
end

程序显示3位输入和20之间的差异。输入小于148.我没有问题。当我输入148或更高时,它不显示128.我该怎么办?

将结果转换回数字时使用的是有符号比较。 如果结果高于128,则会将其视为负数,您的转化将失败。

以下是代码的去混淆和略微清理的版本,如果您将两个有缺陷的jge更改为jae ,则可能会有效。

dosseg
.model small
.stack 100h
.data

; input digits
in_1        db 0
in_10       db 0
in_100      db 0

; output digits
out_1       db 0
out_10      db 0
out_100     db 0

; display
d_prompt    db 'Input 3 digit number: $'
d_result    db 'Result: $'
d_crlf      db 0Dh,10,'$'

.code

    mov ax,@data    ; setup data segment
    mov ds,ax

    lea dx,d_prompt ; display prompt
    mov ah,09h
    int 21h

    mov ah,01h      ; read 3 decimal digits and turn them to numbers
    int 21h
    sub al,30h
    mov in_1,al

    int 21h
    sub al,30h
    mov in_10,al

    int 21h
    sub al,30h
    mov in_100,al

    cmp in_1,00h    ; convert them to a byte
    jg add_hundreds

add_units:
    mov bl,in_100
    add out_1,bl
    jmp check_tens

add_hundreds:
    add out_1, 100
    dec in_1
    cmp in_1,00h
    jne add_hundreds

check_tens:
    cmp in_10,00h
    jg add_tens
    jmp compute

add_tens:
    add out_1,10
    dec in_10
    cmp in_10,00h
    jg add_tens
    jmp add_units

compute:
    sub out_1, 20       ; substract 20 to result

    cmp out_1, 100
    jge above_99        ; ***bug*** should use unsigned comparison (jae)

convert_tens:
    cmp out_1,10
    jge between_10_and_99
    jmp display_result

above_99:
    sub out_1,100       ; convert hundreds
    inc out_100 
    cmp out_1,100
    jge above_99        ; ***bug*** should use unsigned comparison (jae)
    jmp convert_tens

between_10_and_99:
    sub out_1,10        ; convert tens
    inc out_10
    cmp out_1,10
    jge between_10_and_99

display_result:
    add out_100,30h     ; convert digits to characters
    add out_10,30h
    add out_1,30h

    lea dx,d_crlf       ; display line break
    mov ah,09h
    int 21h

    lea dx,d_result     ; display result message
    mov ah,09h
    int 21h

    mov dl,out_100      ; display output
    mov ah,02h
    int 21h

    mov dl,out_10
    mov ah,02h
    int 21h

    mov dl,out_1
    mov ah,02h
    int 21h

    mov ah,4Ch      ; terminate program
    int 21h
end

我自己解决这个问题,能够处理> 255的数字
此版本将处理高达65535的任何内容,然后翻转为0。
否定结果(即输入<20)不能很好地处理。

.model small
.stack 100h
.data

; value to substract
SUB_VALUE   equ 20

; number of digits
NUM_DIGITS  equ 5

; conversion steps
convert label word
num = 1
rept NUM_DIGITS-1
num = num * 10
endm
rept NUM_DIGITS
    dw  num
num = num / 10
endm

; display
d_prompt    db 'Enter a ',NUM_DIGITS+'0',' digits number: $'
d_result    db 0Dh, 0Ah, 'Result: $'

.code

main:
    mov ax,@data    ; setup data segment
    mov ds, ax

    lea dx,d_prompt ; display prompt
    mov ah, 09h
    int 21h

    mov ah,01h      ; read decimal number
    mov cx, NUM_DIGITS
    lea si, convert
    cld
read:
    mov ah,01h  ; read a digit
    int 21h
    sub al, '0' ; convert to number
    mov dl, al
    xor dh, dh
    lodsw       ; multiply by power of 10
    mul dx
    add bx, ax  ; cumulate result
    loop    read

    sub bx, SUB_VALUE   ; do the substraction

    lea dx,d_result     ; display result message
    mov ah,09h
    int 21h

    mov cx, NUM_DIGITS
    lea si, convert
write:
    lodsw       ; power of 10 divider
    xchg    ax,bx   
    xor dx, dx
    div bx  ; divide result by power of 10
    mov bx, dx  ; store remainder
    mov dl, '0' ; print current digit
    add dl, al
    mov ah,02h
    int 21h
    loop    write

    mov ah,4Ch      ; terminate program
    int 21h
end main

花了我一些时间来运行TASM运行DosBox,但它让我想起了我作为DOS黑客的日子:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM