Reputation: 1362
I am beginner in assembly language.I want to print 1-9 with spaces. I want to print like this
1 2 3 4 5 6 7 8 9
Here is my code I am using masm this code hangs command prompt.
Why this is not working?
DATA_SEG SEGMENT
DATA_SEG ENDS
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG , DS:DATA_SEG
MAIN PROC FAR
MOV AH,02
MOV AX,'0'
MOV CX,10
L1:
MOV DX,AX
INT 21H
INC AX
LOOP L1
MOV AX,4C00H
INT 21H
MAIN ENDP
CODE_SEG ENDS
END MAIN
Upvotes: 3
Views: 1650
Reputation: 1362
Wow I print it with simple logic.But I think it is not an efficient solution.
DATA_SEG SEGMENT
ONE DW 48
SPACE DW 32
DATA_SEG ENDS
CODE_SEG SEGMENT
ASSUME CS:CODE_SEG , DS:DATA_SEG
MAIN PROC FAR
MOV AX,DATA_SEG ; TO INTIALIZE DATA SEGMETN
MOV DS,AX
MOV AH,02
MOV CX,10
L1:
MOV DX,ONE
INT 21H
MOV DX,SPACE
INT 21H
INC ONE
LOOP L1
MOV AX,4C00H
INT 21H
MAIN ENDP
CODE_SEG ENDS
END MAIN
Upvotes: 0
Reputation: 363980
MOV AH,02
MOV AX,'0' ; sets ah=0. this is your bug (there may be others).
The following loop prints all the digits, but doesn't leave spaces. I'll leave that up to you. (edit: oops, this prints digits from 0..9, because that's what your code was doing with the inc after the system call, and starting with '0'. Obviously start with '1'
instead.)
MOV AH, 2
mov dl, '0'
.l1:
INT 21H
INC dl
cmp dl, '9'
jle .l1
assuming int 21
/ ah=2 prints the character in dl. int 21
doesn't clobber any registers (except the return value in al
), so you don't need to mov dx, ax
inside the loop. (edit: yes you do, since you need to alternate spaces and digits if you're printing one byte at a time).
Using AH=09h to write a whole string would mean you could construct it efficiently and then print the whole thing. e.g.
;; Not debugged or tested (I don't keep DOS around...)
;; So I may have gotten some 2-character constants in the wrong order
sub sp, 22 ; reserve space (slightly more than necessary because I didn't debug or even test this)
mov di, sp
mov ax, '0 '
.l1:
stosw ; store digit and trailing space into [edi+=2]
inc al
cmp al, '9'
jle .l1
; note that NASM doesn't process \ escapes, but MASM does
mov word [di], '\n$' ; newline and DOS end-of-string marker
mov dx, sp ; dx=input param = start of our buffer
; this only works if DS=SS, I guess. Yay segments.
mov ah, 09h ; DOS write string syscall
int 21h
...
add sp, 22 ; release the stack buffer
...
Note that this code doesn't use a static buffer (bss or data section), unlike most asm examples. This is probably because of segments. Don't spend much time learning about segments, they're not useful for modern programs under modern OSes. See the x86 wiki.
Also note that it doesn't use loop
, because that's slow.
I could have created the string on the stack with push
, but that's maybe more confusing and something you'd never see a compiler do. With push, it would be something like
push '\n$'
mov ax, '9 '
.l1:
push ax ; like stosw in reverse, but with SP instead of DI
dec al
cmp al, '0'
jge .l1
... make the system call with dx=sp
This leaves a trailing space after the 9, though.
Upvotes: 3