我刚开始学习assembly
并且我写了一些练习线,但我被困在需要显示结果的部分。
说明:我有min
值和max
值。我将这些值与array
进行比较,尝试仅显示不在inteval([min,max]
)
以下是我的尝试(我知道我对此非常不好,抱歉!):
include emu8086.inc
ORG 100h
mov cx, 5
verificareMinim:
MOV AX,date
MOV BX,minInterval
CMP AX,BX
JB belowMinResults
loop verificareMinim ; sfarsit pasul 1
verificareMaxim:
MOV AX,date
MOV BX,maxInterval
CMP AX,BX
JA overMaxResults
loop verificareMaxim ; sfarsit pasul 2
belowMinResults:
int 21h
JMP verificareMinim
overMaxResults:
int 21h
JMP verificareMaxim
maxInterval DW 10
minInterval DW 1
date DW -1,-4,11,3,7
RET ; return to operating system.
END ; directive to stop the compiler.
所以,我的问题是:
1)我的代码有什么问题? (问题如上所述,Description
)
2)如何显示结果?
答案 0 :(得分:2)
如果只想打印适合范围的数组,则不需要使用2个循环使其过于复杂。一个循环就足够了。
另一个问题是您没有为int 21h
DOS调用设置任何有意义的参数。
第三个问题是你没有更新你的指针。
第四个问题是您在第一个(cx
)循环后没有再次设置verificareMinim
。
第五个问题是您对签名号码使用无符号条件跳转jb
和ja
。
第六个问题是你的代码进入无限循环,因为当loop verificareMaxim
不再分支到verificareMaxim
时,执行继续belowMinResults
然后(如果int 21h
不会崩溃,也就是说,JMP verificareMinim
使它成为一个无限循环。
第七个问题是ret
指令在您的数据之后,并且永远不会到达。
你可以这样做:
mov si,date ; si points to the array.
; some assemblers want mov si,offset array.
; lea si,date may also be used.
mov cx,5 ; length of array date
修改:打印间隔中不的数字。固定的。
修改:修正了十六进制打印中的错误。
@verify_loop:
mov ax,[si] ; read value from array into ax
cmp ax,[minInterval] ; compare value of ax with the value of min_Interval
; some assemblers want cmp ax,min_Interval
jl @number_is_ok ; jump if less, signed conditional jump.
cmp ax,[maxInterval] ; compare value of ax with the value of max_Interval
; some assemblers want cmp ax,max_Interval
jle @number_not_valid ; jump if less or equal, signed conditional jump.
@number_is_ok:
; the number in ax is valid, print it here.
; I'll do the printing here the easy way: printing in
; hexadecimal, printing in other formats (say, decimal) left as an exercise.
; hint: use div and print always the remainder after converting it to ASCII
; 0...9.
;
; I'll just use int 21h/ah=02h here, dl contains the character to write.
push cx
mov cl,12d ; number of bits to shift.
; start with 12 (it's 16 minus 4).
@print_loop:
mov dx,ax
shr dx,cl ; shift dx cl bits to the right
and dl,0x0F ; leave only the lower nibble (4 bits)
cmp dl,9
jbe @between_0_and_9 ; jump if between or equal to 9
; (unsigned conditional jump)
add dl,('a'-'9'-1) ; Edit: fixed bug here.
; Lowercase hexadecimal letters a-f
; (change to 'A' for uppercase)
@between_0_and_9:
add dl,'0' ; convert to printable ASCII '0'...'9', 'a' ... 'f'
push ax ; according to Ralph Brown's interrupt list,
; int 21h/ah=02 modifies al.
mov ah,2 ; print character to screen
int 21h ; character in dl
pop ax
sub cl,4 ; next time shift 4 bits less
jnc @print_loop ; continue if there's still bits left
pop cx
@number_not_valid:
add si,2 ; next word in array date.
dec cx ; decrement counter.
jnz @verify_loop ; continue if there's still words in array date.
; now everything is done.
mov ax,4C00h
int 21h ; int 21h/ah=4Ch, return to DOS, return code in al.
; int 20h works too, no return code.
; ret works too, but only in .COM files.
maxInterval DW 10
minInterval DW 1
date DW -1, -4, 11, 3, 7