Marviuz
Marviuz

Reputation: 11

Basic assembly language Get & Display system time

i have a code here:

org 100h

mov ah, 2ch
int 21h

mov ah, 2
mov dl, ch
int 21h

mov ah, 2 
mov dl, cl
int 21h     

ret

and what i want is to display the system time. But it displays other characters instead. How do i fix that?

EDIT: how can i add a division operation here? i guess what i want is to divide ch and cl by 10 and print it individually

thanks for answers

Upvotes: 1

Views: 13724

Answers (3)

Marviuz
Marviuz

Reputation: 11

i got it!

org 100h

mov ah, 2ch   ;get time
int 21h       ;

mov hour, ch  
mov mins, cl

mov ah, 0     ;
mov al, hour  ;divide by 10
mov bl, 10    ;
div bl        ;

mov hour1, al 
mov hour2, ah 

mov ah, 2     ;
mov dl, hour1 ;  
add dl, 30h   ;
int 21h       ;
              ;print hour
mov ah, 2     ;
mov dl, hour2 ;
add dl, 30h   ;
int 21h       ;

mov ah, 2     
mov dl, ':'   
int 21h       

mov ah, 0     ;
mov al, mins  ;divide by 10
mov bl, 10    ;
div bl        ;

mov min1, al  
mov min2, ah  

mov ah, 2     ;
mov dl, min1  ; 
add dl, 30h   ;
int 21h       ;
              ;print minuntes
mov ah, 2     ;
mov dl, min2  ;
add dl, 30h   ;
int 21h       ;

ret

hour db ?  ;
mins db ?  ; 
hour1 db ? ;
hour2 db ? ;initialize variables
min1 db ?  ;
min2 db ?  ;

Upvotes: 0

Hamza
Hamza

Reputation: 801

This code might be helpful for you. You can find it here and download also: Timer Tick Example of Assembly Language

[org 0x0100]

    jmp start


incTime: dw 0 
hrs: dw 0
min: dw 0
sec: dw 0

clearScreen:

   push ax
   push di
   push es

   mov ax , 0xB800
   mov es , ax
   mov di , 0
   nextCls:
      mov word [es:di] , 0x0720
      add di , 2
      cmp di , 4000
      jne nextCls

   pop es
   pop di
   pop ax
   ret


printTime:

   push bp
   mov bp , sp
   push ax
   push bx
   push cx
   push dx
   push si
   push di
   push es

   call clearScreen

   mov si , 0  ;counter to use 3 prints i.e. Hrs, Min, Sec
   mov ax , 0xB800
   mov es , ax
   mov di , 142

nextState:

   mov bx , bp
   sub bx , si
   add bx , 8
   mov ax , [bx]    ;BX=BP-SI+8
   mov bx , 10
   mov cx , 0

   nextDigit:
      mov dx , 0
      div bx
      add dl , 0x30
      push dx
      inc cx
      cmp ax , 0
      jnz nextDigit

   nextPos:
      pop dx
      mov dh , 0x07
      mov [es:di] , dx
      add di , 2
      loop nextPos

      add si , 2
      cmp si , 6
      jz return

      mov dl , ':'
      mov [es:di] , dx
      add di , 2
      jmp nextState


   return:
      pop es
      pop di
      pop si
      pop dx
      pop cx
      pop bx
      pop ax
      pop bp

      ret 6

Clock:
   push ax

   inc word [cs:incTime]
   cmp word [cs:incTime] , 18
   jz Reset

   proceedToCall:
      push word [cs:hrs]
      push word [cs:min]
      push word [cs:sec]
      call printTime

      mov al , 0x20 
      out 0x20 , al

      pop ax
      iret

   Reset:
      mov word [cs:incTime] , 0
      inc word [cs:sec]
      cmp word [cs:sec] , 60
      jnz proceedToCall
      mov word [cs:sec] , 0
      inc word [cs:min]
      cmp word [cs:min] , 60
      jnz proceedToCall
      mov word [cs:min] , 0
      inc word [cs:hrs]
      cmp word [cs:hrs] , 24
      jnz proceedToCall
      mov word [cs:hrs] , 0
      jmp proceedToCall


start:
   xor ax , ax
   mov es , ax
   cli
      mov word [es:8*4] , Clock
      mov word [es:8*4+2] , cs
   sti

   mov dx , start
   add dx , 15
   mov cl , 4
   shr dx , cl

   mov ax , 0x3100
   int 0x21

Upvotes: 0

Margaret Bloom
Margaret Bloom

Reputation: 44046

Hours range from 0 to 23.
Minutes from 0 to 59.

They are two digits numbers and as such must be handled.

There is no built-in service that prints numbers, the Int 21/AH=02h prints characters, you need to transform a two digits number (an 8 bit quantity) into a two characters (two 8 bit quantities)1.

This site has plenty of examples, here is one that use only simple instructions.

ORG 100h

mov ah, 2ch           ;Get time
int 21h

mov dl, ch            ;Show hours
call itoa99

mov ah, 02h           ;Show separator
mov dl, ':'
int 21h

mov dl, cl            ;Show minutes
call itoa99    

mov ax, 4c00h         ;Exit
int 21h



;dl = number to display (0..99)
itoa99:
 push bx
 push ax            ;Save registers used

 xor ax, ax         ;AX = 0
 mov al, dl         ;AX = DL

 mov bl, 10d
 div bl             ;AL = AX/10, AH = AX mod 10

 ;AX contains the digits

 add ax, 3030h      ;Transform digit to digitals

 ;ASCII digits starts at 30h, digit X is the char 30h+X

 ;ASCII value: 30h  31h  32h  33h ... 39h
 ;Character:   0    1    2    3   ... 9



 mov bx, ax         ;Save for later 

 ;Show the digits
 mov dl, bl
 mov ah, 02h
 int 21h

 mov dl, bh
 int 21h

 pop ax
 pop bx
 ret

1 A two digits number has... two digits.
Base 10 is a positional system, it means that the number representation is composed of weighted quantities called digits.
Each digit is itself a number, but simple enough to have an unique symbol associated, a digital.
For example the digit 4 is represented with various symbols depending on the culture: '4', 'ד', '四', 'IV', '٤', ...
To display a number in base 10, we first need to extract the digits, then convert the digits to their digitals. The final result is a numeral.
To extract the two base 10 digits of a 0-59 range number, we simply use: d0 = n mod 10, d1 = n / 10.
Convince your self that this indeed gives the correct result and that each di is between 0 and 9.

Upvotes: 4

Related Questions