Я писал программу сборки x86 для вывода числа в шестнадцатеричном формате. Программа была собрана с использованием nasm и файла изображения, запускаемого qemu. Поведение программы сильно смутило меня. Как показывает рабочая программа ниже, мне не нужно будет добавлять 0x30 в цифру, чтобы заставить ее печатать символ этой цифры.x86 Сводный номер буфера строки в ASCII
; Boot sector code offset: 0x7c00
[org 0x7c00]
mov dx, 0x1fb6 ; The hexadecimal to be printed
call print_hex ; call the function
jmp $ ; jump infinitely
%include "print_string.asm" ; Include the print_string function
print_hex:
pusha ; push all registers to stack
mov ax, 0x4 ; rotate through the number four times
print_hex_loop:
cmp ax, 0x0 ; compare the counter with 0
jle print_hex_end ; if it is zero then jump to the end
mov cx, dx ; move dx to cx
and cx, 0x000F ; take the lower four binary digits of cx
cmp cx, 0xa ;compare the digits with 0xa
jge print_hex_letter ; if it is larger than a, jump to printing character
add cx, 0x0 ; otherwise print the ascii of a number
jmp print_hex_modify_string ; jump to routine for modifing the template
print_hex_letter:
add cx, 0x7 ; print the ascii of a letter
print_hex_modify_string:
mov bx, HEX_OUT ; bring the address of HEX_OUT into dx
add bx, 0x1 ; skip the 0x
add bx, ax ; add the bias
add byte [bx], cl ; move the character into its position
shr dx, 4 ; shift right 4 bits
sub ax, 0x1 ; subtract 1 from the counter
jmp print_hex_loop ; jump back to the start of the function
print_hex_end:
mov bx, HEX_OUT ; move the address of HEX_OUT to bx
call print_string ; call the function print_string
popa ; pop all registers from stack
ret ; return to calling function
HEX_OUT:
db '0x0000',0 ; The template string for printing
times 510-($-$$) db 0 ; fill zeros
dw 0xaa55 ; MAGIC_FLAG for boot
boot_sect.asm
print_string:
pusha
mov ah, 0x0e
mov al, [bx]
print_string_loop:
cmp al, 0x0
je print_string_end
int 0x10
add bx, 0x1
mov al, [bx]
jmp print_string_loop
print_string_end:
popa
ret
print_string.asm
Вывод этой программы является то, что я ожидал, но когда я попытался добавить 0x30 на цифры, чтобы получить ASCII код цифры, результат был тарабарщин. Есть ли какой-то трюк или я не хватает некоторых ключевых моментов здесь?
Спасибо!
Поскольку 'HEX_OUT: db '0x0000'' является ** строкой **, которая представляет символы ASCII для' 0 'уже. Не нужно добавлять 0x30 к значениям, которые были инициализированы ASCII '0'. Также обратите внимание, что вызов 'print_hex' более одного раза не будет работать, потому что, как этот код был написан, ожидалось, что' HEX_OUT' инициализируется строкой '0x0000'. –
OK Я вижу, спасибо! –
Из-за 'add byte [bx], cl' .., если вы сделаете' mov byte [bx], cl', вам придется сначала добавить '' 0'' или '' A'-10' '. – Ped7g