Which assembler?
Posted: Sun Apr 13, 2008 8:40 am
Which assembler can assemble this code?
Nasm or Masm or ....what?
; stopwatch
DOSSEG
.MODEL SMALL
.STACK 4096
.DATA
Instructions db 'STOPWATCH',13,10
db '---------',13,10
db ' (S)tart S(t)op (Q)uit',13,10
db 13,10,' $'
Blank db ' $'
StartRow db ? ; position on screen of timer
StartCol db ? ; position on screen of timer
Running db 0 ; is timer running ?
TimerStart dd ? ; start value of timer
TempStr db 1,2 ; temporary storage for STDIN input
t2 db 80 dup (0)
t3 db 13,10,'$'
.CODE
ProgramStart:
mov ax,SEG _DATA ; set up data segment
mov ds,ax
lea dx,Instructions ; output instructions
mov ah,9
int 21h
mov ah,3 ; get current position on screen
xor bh,bh
int 10h
mov StartRow,dh
mov StartCol,dl
startkeys: ; loop to get/process keystrokes
mov ah,1 ; check keyboard status
int 16h
jz updateloop ; update if no keys available
mov ah,0 ; get keystroke
int 16h
cmp al,'q' ; check for QUIT key
je theend
cmp al,'s' ; check for START key
jne checkstop ; jump to next check
call start
jmp updateloop ; update display
checkstop:
cmp al,'t' ; check for STOP key
jne startkeys ; continue loop
call stop
updateloop:
cmp Running,0
je startkeys ; continue loop if timer not running
call update ; update screen
jmp startkeys ; continue loop
theend:
lea dx,t3 ; move cursor to next line
mov ah,9
int 21h
mov ah,4ch ; terminate program
int 21h
update PROC ; procedure to update timer display
mov ax,0040h ; set ES to point to BIOS data area
mov es,ax
mov ax,es:[006Ch] ; get system clock value
mov dx,es:[006Eh]
sub ax,word ptr TimerStart ; get time difference
sbb dx,word ptr TimerStart+2
mov bx,65535
div bx ; get hours in AX
mov cx,ax ; save hours value in CX
xor ax,ax
xchg ax,dx ; swap remainder into AX
mov bx,1092
div bx ; get minutes in dx
mov si,ax ; save minutes value in SI
xor ax,ax
xchg ax,dx ; swap remainder into AX
mov bx,18
div bx ; get seconds in ax
push ax ; save seconds
push si ; save minutes
push cx ; save hours
xor bh,bh ; put cursor at old position
mov dh,StartRow
mov dl,StartCol
mov ah,2
int 10h
pop ax ; restore hours
call writesint ; output hours
mov dl,':' ; output colon
mov ah,2
int 21h
pop ax ; restore minutes
call writesint ; output minutes
mov dl,':' ; output colon
mov ah,2
int 21h
pop ax ; restore seconds
call writesint ; output seconds
lea dx,Blank ; erase any digits left from old time
mov ah,9
int 21h
ret
update ENDP
start PROC ; procedure to start timer
mov ax,0040h ; set ES to point to BIOS data area
mov es,ax
mov ax,es:[006Ch] ; get system clock value
mov dx,es:[006Eh]
mov word ptr TimerStart,ax ; store clock value in TimerStart
mov word ptr TimerStart+2,dx
mov Running,1 ; set timer flag
ret
start ENDP
stop PROC ; procedure to stop timer
mov Running,0 ; clear timer flag
ret
stop ENDP
writesint PROC ; outputs the integer in the AX register
push ax ; save all registers used
push bx
push cx
push dx
push si
mov bx,10 ; radix = decimal = 10
xor si,si ; initialize digit counter
startdiv:
xor dx,dx
div bx ; divide no by 10
push dx ; save remainder
inc si ; increment digit counter
cmp ax,0 ; check for end of divisions
jne startdiv
mov cx,si ; set digit counter
mov bx,0 ; initialize position counter
makeletters:
pop ax ; get digit
add al,48 ; make integer --> ascii value
mov [t2+bx],al ; insert digit into string
inc bx ; increment position counter
loop makeletters
mov [t2+bx],'$' ; put end-of-string marker
mov ah,09h ; output integer as string
lea dx,t2
int 21h
pop si ; restore registers
pop dx
pop cx
pop bx
pop ax
ret ; return to point of call
writesint ENDP
END ProgramStart
Nasm or Masm or ....what?
; stopwatch
DOSSEG
.MODEL SMALL
.STACK 4096
.DATA
Instructions db 'STOPWATCH',13,10
db '---------',13,10
db ' (S)tart S(t)op (Q)uit',13,10
db 13,10,' $'
Blank db ' $'
StartRow db ? ; position on screen of timer
StartCol db ? ; position on screen of timer
Running db 0 ; is timer running ?
TimerStart dd ? ; start value of timer
TempStr db 1,2 ; temporary storage for STDIN input
t2 db 80 dup (0)
t3 db 13,10,'$'
.CODE
ProgramStart:
mov ax,SEG _DATA ; set up data segment
mov ds,ax
lea dx,Instructions ; output instructions
mov ah,9
int 21h
mov ah,3 ; get current position on screen
xor bh,bh
int 10h
mov StartRow,dh
mov StartCol,dl
startkeys: ; loop to get/process keystrokes
mov ah,1 ; check keyboard status
int 16h
jz updateloop ; update if no keys available
mov ah,0 ; get keystroke
int 16h
cmp al,'q' ; check for QUIT key
je theend
cmp al,'s' ; check for START key
jne checkstop ; jump to next check
call start
jmp updateloop ; update display
checkstop:
cmp al,'t' ; check for STOP key
jne startkeys ; continue loop
call stop
updateloop:
cmp Running,0
je startkeys ; continue loop if timer not running
call update ; update screen
jmp startkeys ; continue loop
theend:
lea dx,t3 ; move cursor to next line
mov ah,9
int 21h
mov ah,4ch ; terminate program
int 21h
update PROC ; procedure to update timer display
mov ax,0040h ; set ES to point to BIOS data area
mov es,ax
mov ax,es:[006Ch] ; get system clock value
mov dx,es:[006Eh]
sub ax,word ptr TimerStart ; get time difference
sbb dx,word ptr TimerStart+2
mov bx,65535
div bx ; get hours in AX
mov cx,ax ; save hours value in CX
xor ax,ax
xchg ax,dx ; swap remainder into AX
mov bx,1092
div bx ; get minutes in dx
mov si,ax ; save minutes value in SI
xor ax,ax
xchg ax,dx ; swap remainder into AX
mov bx,18
div bx ; get seconds in ax
push ax ; save seconds
push si ; save minutes
push cx ; save hours
xor bh,bh ; put cursor at old position
mov dh,StartRow
mov dl,StartCol
mov ah,2
int 10h
pop ax ; restore hours
call writesint ; output hours
mov dl,':' ; output colon
mov ah,2
int 21h
pop ax ; restore minutes
call writesint ; output minutes
mov dl,':' ; output colon
mov ah,2
int 21h
pop ax ; restore seconds
call writesint ; output seconds
lea dx,Blank ; erase any digits left from old time
mov ah,9
int 21h
ret
update ENDP
start PROC ; procedure to start timer
mov ax,0040h ; set ES to point to BIOS data area
mov es,ax
mov ax,es:[006Ch] ; get system clock value
mov dx,es:[006Eh]
mov word ptr TimerStart,ax ; store clock value in TimerStart
mov word ptr TimerStart+2,dx
mov Running,1 ; set timer flag
ret
start ENDP
stop PROC ; procedure to stop timer
mov Running,0 ; clear timer flag
ret
stop ENDP
writesint PROC ; outputs the integer in the AX register
push ax ; save all registers used
push bx
push cx
push dx
push si
mov bx,10 ; radix = decimal = 10
xor si,si ; initialize digit counter
startdiv:
xor dx,dx
div bx ; divide no by 10
push dx ; save remainder
inc si ; increment digit counter
cmp ax,0 ; check for end of divisions
jne startdiv
mov cx,si ; set digit counter
mov bx,0 ; initialize position counter
makeletters:
pop ax ; get digit
add al,48 ; make integer --> ascii value
mov [t2+bx],al ; insert digit into string
inc bx ; increment position counter
loop makeletters
mov [t2+bx],'$' ; put end-of-string marker
mov ah,09h ; output integer as string
lea dx,t2
int 21h
pop si ; restore registers
pop dx
pop cx
pop bx
pop ax
ret ; return to point of call
writesint ENDP
END ProgramStart