我正在为class做一个项目,它按照准则的要求工作,尽管我想知道是否有更好的方法来实现一些东西。在另一个项目中,我因为一个不必要的"mov"而被扣了几分。这是问题1。
如果——否则(34分):编写一个程序,要求用户输入一个数字。如果这个数字小于5,你会这样说,你会给它加5,然后把它存储在一个变量中;如果这个数字大于5,你就会这样说,然后从中减去5,把它存储到一个变量里;如果数字是5,你将给它加3,然后这样说,把它保存在一个变数里。
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您输入了:
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中,但每次我将mov函数转换为AH时,无论是字符串打印还是字符打印,寄存器值都会发生变化。为了避免变量(因为它不是需求的一部分)或将其分配到内存(我们还没有学到),我将数据移动到另一个寄存器。这对任何一个程序来说都是不必要的"mov"吗?
编辑:我意识到后AL=DL
mov ah, 06h
mov dl, 0ah
int 21h ;AL = DL after execution
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
,而是失败,因为相等是在jl
和jg
之后剩下的唯一状态。此外,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:
你的第二个项目也可以从这些建议中受益。