1

In assembly language I want to print a colored string
"-- WELCOME TO E-VOTING MANAGEMENT SYSTEM --" in forward order but the string is printing in reverse order. Here is the output.
Below is my code:

;print screen
mov cx,45
mov si,-1
c1:
inc si
mov al,msg3[si]
mov ah,9
mov bh,0
mov bl,00110100b
int 10h
loop c1
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 2
    Nice effect :) The int10/9 function does not move the cursor. However it does take a repeat count in `CX`. You print the first character 45 times, then the second 44 times and so on. This means the last repetition remains visible, hence the apparent reversal. – Jester Dec 13 '21 at 22:10

1 Answers1

1

This BIOS.WriteCharacterWithAttribute function 09h does not advance the cursor. You can use the BIOS.Teletype function 0Eh for that purpose.

Since the BIOS.WriteCharacterWithAttribute function 09h uses the CX register for a repetition count, it will be best to not use CX for a loop counter. Below code use DI. This code also avoids using the LOOP instruction which is infamous for being slow! See Why is LOOP so slow?.

;print screen
  mov  di, 45
  mov  si, -1
  mov  cx, 1       ; Repetition count
  mov  bx, 0034h   ; DisplayPage 0, Color RedOnCyan
TheLoop:
  inc  si
  mov  al, msg3[si]
  mov  ah, 09h
  int  10h
  mov  ah, 0Eh
  int  10h
  dec  di
  jnz  TheLoop

It is possible to use the offset SI by which we address the characters as our loop counter. In a string that has 45 characters, the very last character will be at offset 44, so that's the value we need to have reached at loop exit:

;print screen
  mov  si, -1
  mov  cx, 1       ; Repetition count
  mov  bx, 0034h   ; DisplayPage 0, Color RedOnCyan
TheLoop:
  inc  si
  mov  al, msg3[si]
  mov  ah, 09h
  int  10h
  mov  ah, 0Eh
  int  10h
  cmp  si, 44
  jne  TheLoop

One further improvement would start the offset SI at 0, using the one byte shorter encoding of xor si, si. This influences the way we need to check for the loop exit!

;print screen
  xor  si, si
  mov  cx, 1       ; Repetition count
  mov  bx, 0034h   ; DisplayPage 0, Color RedOnCyan
TheLoop:
  mov  al, msg3[si]
  mov  ah, 09h
  int  10h
  mov  ah, 0Eh
  int  10h
  inc  si
  cmp  si, 45
  jb   TheLoop

And instead of using a fixed count for the string length, you could also easily use a string terminator like zero.

;print screen
  xor  si, si
  mov  cx, 1       ; Repetition count
  mov  bx, 0034h   ; DisplayPage 0, Color RedOnCyan
TheLoop:
  mov  al, msg3[si]
  test al, al
  jz   Done
  mov  ah, 09h
  int  10h
  mov  ah, 0Eh
  int  10h
  inc  si
  jmp  TheLoop
Done:

  ...

msg3 db "--  WELCOME TO E-VOTING MANAGEMENT SYSTEM  --", 0
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 1
    You already have SI as a loop counter, you could just `cmp si, 45` or `cmp si,di` instead of also counting down another register. – Peter Cordes Dec 14 '21 at 02:30