HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

8086/DOS assembly keyboard I=input, data loss in registers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
lossinput8086assemblydosregisterskeyboarddata

Problem

I am working on a project for class, and it works as required by the rubric, though I am wondering if there is a slightly better way to implement a few things. I was docked a few points for an unnecessary mov in another project.

Problem 1:


"If—else (34 points): Write a program that asks the user to enter a
single digit. If that digit is less 5, you will state so and you will
add 5 to it and store it in a variable; if the digit is greater than
5, you will state so and then subtract 5 from it and store it in a
variable; if the digit is 5, you will add 3 to it and state so and
store it in a variable."

```
org 100h
mov dx, offset start ;move start of string address 'start' into dx
mov ah, 09h
int 21h ;print the string stored at DS:DX
mov ah, 01h ;function for getting keyboard input
int 21h
sub al, 30h ;subtract 30h to store our number as hexadecimal
mov bl, al ;copying data to BL as the following commands manipulate the data
;at AL.
cmp bl, 5 ;BL = AL
jz ifZero ;jump to ifZero if BL = 5
jl ifLess ;jump to isLess if BL 5

ifZero: ;direct console output function
mov ah, 06h
mov dl, 0Ah
int 21h
mov dl, 0Dh
int 21h ;print newline and character return
add bl, 03h ;add 3 to BL, BL = 8
mov temp, bl
mov dx, offset eq ;move start of string address 'eq' into dx
mov ah, 09h
int 21h ;print string
jmp exit ;unconditional jump to end program

ifLess: ;direct console output function
mov ah, 06h
mov dl, 0aH
int 21h
mov dl, 0Dh
int 21h ;print newline and character return
add bl, 05h ;add 5 to BL
mov temp, bl
mov dx, offset less ;move start of string address 'less' into dx
mov ah, 09h
int 21h ;print string
jmp exit ;unconditional jump to end program

ifGreater:
mov ah, 0

Solution

Write a program that asks the user to enter a single digit

This is where your program has its first error. You trust the user at the keyboard to actually input a digit, but your program should make sure it indeed got a digit!

InputAgain:
mov dx, offset start ;move start of string address 'start' into dx
mov ah, 09h
int 21h ;print the string stored at DS:DX
mov ah, 01h ;function for getting keyboard input
int 21h
cmp al, '0'
jb InputAgain
cmp al, '9'
ja InputAgain
sub al, 30h ;subtract 30h to store our number as hexadecimal


The solution I've presented above will work out nicer if you add a single CR code to the message at start.

start db 13,"Please enter a number: $"


cmp bl, 5 ;BL = AL
jz ifZero ;jump to ifZero if BL = 5
jl ifLess ;jump to isLess if BL 5
ifZero:


The first improvement you should do is making use of the possibility to fall-through in the code. Don't use jz ifZero but rather fall through as equality is the only state that remains after jl and jg. Also ifEqual would be a more correct name for this state.

cmp bl, 5 ;BL = AL
jl ifLess ;jump to isLess if BL 5
ifEqual:


A second optimization will be to get rid of all of those direct console outputs for CR and LF. You should incorporate these in the messages that you will print. Doing so will also remove the need to copy AL to BL using mov bl, al (you specifically asked this):

less db 13,10,"Less than 5... adding 5 $"
great db 13,10,"Greater than 5... subtracting 5 $"
eq db 13,10,"Equal to 5... adding 3 $"


Do observe that I wrote 13,10 and not 10,13. On the DOS platform convention dictates the use of CRLF=13,10. This might not seem too important to you but recently I came across a question on Stack Overflow where someone suffered a malfunctioning emulator precisely because of this!

-
Here's another opportunity to fall through:

jmp exit ;unconditional jump to end program
exit:


-
Yet another such opportunity:

jmp newLine ;we unconditionally jump to the newLine
newLine:


Your second program can benefit from these advices too.

Context

StackExchange Code Review Q#123938, answer score: 3

Revisions (0)

No revisions yet.