问题
I'm trying to display 0-9 diagonally in assembly, but the output puts my diagonally printed numbers in the middle of the window.
Here is the code:
start:
mov ah, 02h
mov cl, 0Ah ;counter (10)
mov dx, 02h
;mov bx, 02h
mov dl, 30h ;start printing 0-9
mov dh, 02h ;start row
mov al, 02h
int 21h
again:
int 10h
int 21h
;add dx, 01h
inc dh
inc dx
inc al
loop again
mov ax, 4c00h
int 21h
The output should be:
0 1 2 3 4 5 6 7 8 9
The current output prints that, but on the middle of the window. I've tried adding a new register bh
and use it to put my cursor on my current position when I execute the file. How can I display it starting on my cursor? Should I put it on a loop and increment register ah
?
回答1:
Your current program fails because you horribly mix 2 system functions that happen to have the same function number 02h, but that expect to receive totally different information in the DL
register. The DOS OutputCharacter function expects a character code and you set it at 48, but the BIOS SetCursor function will interpret the same value 48 as the column. That's why the results are displayed in the middle of the screen!
Since you say you want to start from the current cursor position, which will nearly always be at the left edge of the screen at program start, there's no need to set the cursor position at all.
mov ah, 02h
mov dl, "0"
Next:
push dx ;Preserve current character
int 21h
mov dl, " " ;Your desired output shows this space?
int 21h
mov dl, 10 ;Linefeed moves the cursor 1 line down
int 21h
pop dx ;Restore current character
inc dl
cmp dl, "9"
jbe Next
Instead of using a separate counter, you can decide about looping back by looking at the value in the incremented DL
register.
Notice that you used the loop
instruction which depends on the CX
register but that you only initialized the CL
bottom half of it! That's often a reason of program crashing.
EDIT
Given that DOSBox emits both Carriage return and Linefeed when asked to display character 10 (brought to my attention in this comment by Michael Petch), I wrote this next little program that I tested for accuracy in the latest DOSBox available which is version 0.74.
ORG 256 ;Create .COM program
mov ah, 02h ;DOS.DisplayCharacter
mov dx, "0" ;DH is spaces counter, DL is current character
jmps First ;Character "0" has no prepended spaces!
Next:
push dx ;(1)
mov dl, " "
Spaces:
int 21h
dec dh
jnz Spaces
pop dx ;(1)
First:
int 21h ;Display character in DL
push dx ;(2)
mov dl, 10 ;Only on DOSBox does this do Carriage return AND Linefeed !
int 21h
pop dx ;(2)
add dx, 0201h ;SIMD : DH+2 and DL+1
cmp dl, "9"
jbe Next
mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
来源:https://stackoverflow.com/questions/47394404/print-numbers-diagonally-in-assembly