how do I display to the screen using writeHexByte in a loop?

Viewed 31

I got displayChar character showing on the boot up. Now how do i add writeHexBytes which then displays on the screen using writeHexByte in a loop, and writeHexWord.

*writeHexByte expects an 8-bit register displays it by calling convertHexNibble and using writeChar

*writeHexWord expects a 16-bit register or memory parameter and displays each byte by calling writeHexByte

so after writing characters it needs to display machine code that macro writeChar implements. And display using writeHexBytes in a loop

Code attempted

 # Macro definition
.macro convertHexNibble register
    cmpb $10, \register
    jl 1f
    # process here is >=10
    add $0x37, \register
    jmp 2f  
    # process here is <=10
    1:
    add $0x30, \register    
    2:
    # expect the register to now be the ascii code
.endm

#.macro writeHexByte register
#convert
#.endm

.macro displayChar character color
mov $0x09, %ah
mov \character, %al  
mov $0x00, %bh 
mov \color, %bl 
mov $0x01, %cx
int $0x10
.endm

#set defualts values to move cursor off screen
.macro moveCursor row = $0xff column = $0xff
mov $0x02, %ah # ah = 02h moves the cursor row 2 col 2
mov $0x00, %bh # bh = 0 page
mov $0x02, %dh 
mov $0x02, %dl # dl=1
int $0x10
.endm

.macro sumArray array number result

# assume array is an array of bytes
#therefore the accumulator is just %al (8bits)
      mov $\number, %cx  # AX will serve as a counter for 
                     # the number of words left to be summed 
      mov $0, %ax  # BX will store the sum
      mov \array, %bx  # CX will point to the current 
                     # element to be summed
top:  add (%bx), %cx
      inc %bx  # move pointer to next element
      dec %ax  # decrement counter
      jnz top  # if counter not 0, then loop again
done: mov %ax, \result  # done, store result in "array"

.endm

# The main boot processing code
.code16
.text
.global _start
_start:

mov $06, %al
convertHexNibble %al
displayChar %al, $0xe3
moveCursor %ah
mov $0x0A, %al
convertHexNibble %al
displayChar %al, $0xe3

sumArray $x 4 sum

# writtenHexWord $sum

# move Cursor off screen invisble
moveCursor

cli # clear interrupts
hlt
x: .byte 1, 5, 2, 10    
#   char x[] = {1, 5, 2, 10};      
sum: .byte 0
# char sum = 0;

. = _start + 510
.byte 0x55
.byte 0xAA
1 Answers

writeHexByte expects an 8-bit register displays it by calling convertHexNibble and using writeChar

writeHexWord expects a 16-bit register or memory parameter and displays each byte by calling writeHexByte

Your code gets bloated because of the excessive use of macro's. Each time that you invoke a macro, its entire code, after parameter expansion, gets inserted right where the invokation takes place. Most of what you're doing with macro's should be done with subroutines. For both a shorter and faster program!

Nonetheless, I will show you a solution that builds upon your current macro's.

  • The displayChar macro had to be expanded with an api call to the BIOS.Teletype function 0x0E, so that consecutive characters don't get printed at the same cursor position.
  • The convertHexNibble macro has been optimized by doing the addition by 0x30 first. It has to happen in both cases, doesn't it.
.macro displayChar character color
    mov  $0x01, %cx
    mov  $0x00, %bh 
    mov  \color, %bl 
    mov  $0x09, %ah         # BIOS.WriteColoredCharacter
    mov  \character, %al  
    int  $0x10
    mov  $0x0E, %ah         # BIOS.Teletype
    int  $0x10
.endm

.macro convertHexNibble register
    add  $0x30, \register    
    cmpb $0x39, \register
    jbe  1f
    # process here is >=10
    add  $0x07, \register
    1:
    # expect the register to now be the ascii code
.endm

.macro writeHexByte register
    mov  \register, %al
    push %ax
    shr  $4, %al
    convertHexNibble %al
    displayChar %al, $0xE3
    pop  %ax
    and  $15, %al
    convertHexNibble %al
    displayChar %al, $0xE3
.endm

.macro writeHexWord register
    mov  \register, %ax
    push %ax
    writeHexByte %ah
    pop  %ax
    writeHexByte %al
.endm

And this is the corrected version of your sumArray macro that really, really should not exist as a macro!!

If you write this comment "# assume array is an array of bytes", why then do you add words to the current sum in %cx?
And most of the other comments didn't even match the code.

.macro sumArray array number result
    # assume array is an array of bytes
    # therefore the accumulator is just %al (8bits)
      mov  $\number, %cx
      mov  \array, %bx
      xor  %ax, %ax
top:  add  (%bx), %al
      inc  %bx          # move pointer to next element
      dec  %cx          # decrement counter
      jnz  top          # if counter not 0, then loop again
      mov  %al, \result # (*)
.endm

(*) Because sum is defined to be a byte (sum: .byte 0), your final store should never write the full word from %ax.

Related