assembly 如何在循环中使用writeHexByte在屏幕上显示?

ct3nt3jp  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(166)

我得到了显示字符显示在 Boot 。现在我如何添加writeHexBytes,然后显示在屏幕上使用writeHexByte在一个循环,并writeHexWord。

  • writeHexByte需要一个8位寄存器,通过调用convertHexNibble并使用writeChar显示该寄存器
  • writeHexWord需要16位寄存器或内存参数,并通过调用writeHexByte显示每个字节

所以在写入字符后,它需要显示宏writeChar实现的机器码。并在循环中使用writeHexBytes显示

已尝试代码

# 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
wbgh16ku

wbgh16ku1#

  • writeHexByte* 需要一个8位寄存器,通过调用 convertHexNibble 并使用 writeChar 显示该寄存器
  • writeHexWord* 需要16位寄存器或内存参数,并通过调用 writeHexByte 显示每个字节
    您的程式码因为过度使用宏而变得臃肿。每次您叫用宏时,其整个程式码,在参数展开之后,会插入到叫用发生的地方。您所做的大部分宏应该用副程式来完成。为了更短和更快的程式!

尽管如此,我还是将向您展示一个基于当前宏的解决方案。

  • displayChar 宏必须通过对BIOS.Teletype函数0x 0 E的API调用进行扩展,以便连续字符不会在同一光标位置打印。
  • convertHexNibble 宏已经优化,先加0x 30。这两种情况下都会发生,不是吗?
.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

这是您的 sumArray 宏的更正版本,它真的不应该以宏的形式存在!!
如果你写这个注解“# assume array is an array ofbytes",那么你为什么要在%cx中的当前和中添加words
大多数其他评论甚至都不符合代码。

.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

(*)由于 sum 定义为字节(sum: .byte 0),因此最终存储不应写入%ax中的完整字。

相关问题