8086汇编 - 更好的数据存储/操作?

时间:2016-03-25 22:09:43

标签: loops assembly

我正在为一个类的项目工作,它按照量规的要求工作,不过我想知道是否有更好的方法来实现一些东西。我在另一个项目中为一个不必要的'mov'停靠了几点。这是问题1。

“If-else(34分):写一个程序,要求用户输入一个数字。如果该数字小于5,你将说明,你将加5,并将其存储在一个变量中;如果数字大于5,你将说明,然后从中减去5并将其存储在一个变量中;如果数字是5,你将向它添加3并说明并将其存储在一个变量中。“ p>

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
jg ifGreater           ;jump to ifGreater 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, 06h            
mov dl, 0ah
int 21h
mov dl, 0dh
int 21h                ;print newline and character return
sub bl, 05h            ;subtract 5 from BL
mov temp, bl
mov dx, offset great   ;move starting address of string 'great' into dx
mov ah, 09h
int 21h                ;print string
jmp exit               ;unconditional jump to end program


exit:
ret

temp db ? 
start db "Please enter a number: $"
less db "Less than 5... adding 5 $"
great db "Greater than 5... subtracting 5 $"
eq db "Equal to 5... adding 3 $"
在这种情况下,不需要'mov bl,al'吗?通过反汇编程序运行表明AL中的数据在大多数命令之后发生了变化。这应该发生吗?有没有更好的方法呢?

问题3: 反控制循环。程序将要求用户输入一个字符然后显示 带有标签五次的角色 例如: 输入一个字符:A 您输入了:A

org 100h
mov cx, 05h             ;counter controlled loop, start as 5

LabelLoop:
mov dx, offset prompt   ;move string offset to dx
mov ah, 09h             ;function for printing string from dx
int 21h
mov ah, 01h             ;function to read character from keyboard
int 21h    
mov bl, al              ;preserving character read by copying to BL
                        ;as register data for AL will be changing
                        ;due to various functions
mov ah, 06h             ;function for direct console output
mov dl, 0ah
int 21h
mov dl, 0dh             ;these just make the text appear on a new
                    ;line
int 21h
mov dx, offset output   ;move the memory offset of output to dx
mov ah, 09h             ;printing another string
int 21h
mov ah, 02h             ;function to write a character to console
                        ;gets the value from DL
mov dl, bl                  ;so we copy BL to DL and print it
int 21h
jmp newLine             ;we unconditionally jump to the newLine
                        ;label and print a new line for the program
                        ;to run again

newLine:
mov ah, 06h
mov dl, 0ah
int 21h
mov dl, 0dh
int 21h
loop LabelLoop         ;we jump to LabelLoop and CX = CX - 1

mov dx, offset goodbye
mov ah, 09h
int 21h

ret

prompt db 'Enter a character: $'
output db 'You entered: $'
goodbye db 'Good bye!$'

所以,我对这些问题的疑问是,还有更好的方法吗?键盘输入存储在AL中,但是每次我对AH执行mov功能时,寄存器值都会改变,无论是字符串打印还是字符打印。为了避免变量(因为它不是需求的一部分)或将其分配给内存(我们还没有学习),我将数据移动到另一个寄存器。这对于任何一个程序来说都是不必要的'mov'吗?

编辑:我意识到在

之后AL = DL
mov ah, 06h
mov dl, 0ah
int 21h       ;AL = DL after execution

1 个答案:

答案 0 :(得分:3)

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

您应该做的第一项改进是利用在代码中落实的可能性。不要使用jz ifZero,而是要落实,因为相等是jljg之后唯一的状态。 ifEqual 对于此状态也是更正确的名称。

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

第二个优化是摆脱CR和LF的所有直接控制台输出。您应该将这些内容合并到要打印的消息中。这样做也将无需使用mov bl, al将AL复制到BL(您特别要求):

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 $"

这是另一个失败的机会:

jmp exit               ;unconditional jump to end program
exit:

您的第二个计划也可以从这些建议中受益。