[英]Convert hexadecimal number to hexadecimal string in assembly language (NASM) (debug)
好的,在其他人将此问题标记为重复之前。 让我非常清楚地说明,这与其说是逻辑问题,不如说是调试问题。 据我所知,逻辑是正确的,因为如果我在每次操作后单独打印bx
寄存器中的值,那么我会得到正确的输出。 问题是将结果存储在bx
寄存器中应该会改变它所持有的内存位置,而这不会发生。
所以,这些天我正在 NASM 中学习汇编语言。 我正在关注一个 pdf 文档,该文档要求您打印一个十六进制数(将十六进制数转换为十六进制字符串,然后打印它)。
我已经编写了代码,但它似乎没有打印正确的十六进制数。 另一方面,如果我只是在以下代码片段中打印变量FINAL_ST
而不调用INIT
(这是将十六进制数转换为十六进制字符串的开始),它工作正常并打印0x0000
。
我已经搜索了多次,但无济于事。
我发现 gdb 可用于调试nasm
程序,但当输出是.bin
文件时,我无法理解如何使用它。
我还尝试为这段代码构建一个控制流图来理解执行流程,但找不到合适的工具。 :(
代码:
[org 0x7c00]
mov ax, 0x19d4
mov bx, FINAL_ST + 5
; jmp PRINTER ; works :/
jmp INIT
NUM:
add dx, 0x0030
mov [bx], dx
jmp CONT
ALPHA:
add dx, 0x0037
mov [bx], dx
jmp CONT
CONT:
dec bx
shr ax, 4
cmp ax, 0x0000
jne INIT
je PRINTER
INIT:
mov dx, 0x000f
and dx, ax
cmp dx, 0x000a
jl NUM
jge ALPHA
;STRING PRINTER
PRINTER:
mov bx, FINAL_ST
mov ah, 0x0e
jmp PRINT ; this doesn't work
PRINT:
mov al, [bx]
int 0x10
inc bx
cmp byte[bx], 0x00
jne PRINT
FINAL_ST:
db "0x0000", 0x00
END:
times 510 - ($ - $$) db 0
dw 0xaa55
使用的命令:
nasm boot_hex1.asm -f bin -o boot_hex1.bin
qemu-system-x86_64 boot_hex1.bin
我得到的输出为0x1
而预期的输出为0x19D4
。
你的问题在看起来像这样的两行上:
mov [bx], dx
这会将DX 中的 16 位值移动到BX 中指定的地址。 由于 x86 是小端字节序,这会在循环的每次迭代中将DL移动到[BX]
,将DH 移动到[BX+1]
。 由于DH在您的代码中始终为零,因此在将每个字符写入FINAL_ST
缓冲区后,NUL 会终止字符串。
问题是您真的在考虑使用DL 中的字节更新BX指向的内存。 将两行更改为:
mov [bx], dl
我有一个关于引导加载程序提示的 Stackoverflow 答案。 提示 #1 是:
当 BIOS 跳转到您的代码时,您不能依赖具有有效值或预期值的 CS、DS、ES、SS、SP 寄存器。 当您的引导加载程序启动时,它们应该被适当地设置。 您只能保证您的引导加载程序将从物理地址 0x00007c00 加载并运行,并且引导驱动器编号已加载到 DL 寄存器中。
至少您应该将DS设置为零,因为您使用的是 0x7c00 的ORG
(原点)。 在将控制权转移到引导加载程序之前,您不能假设 BIOS 会将DS设置为零。 它在QEMU 中工作,因为它的 BIOS 在DS 中已经具有值 0x0000。 并非所有硬件和模拟器都能保证这一点。
如果有人需要,这是一个具有工作解决方案的过程......
; Use: convert a hex value into a string
; Input: hex value(+10), string pointer(+12)
; Output: None
HEX_BINARY_LEN equ 4
ALPHA_MIN equ 000ah
ALPHA_ASCII equ 55
DECIMAL_ASCII equ 48
HEX_VALUE equ 10
STRING_PTR equ 12
;----------------------------------------------------------------
proc hexToString
push bp
push bx
push ax
push dx
mov bp, sp
mov bx, [bp + STRING_PTR]
add bx, 3 ; because we start from the end
mov ax, [bp + HEX_VALUE]
digitLoop:
mov dx, 000fh
and dx, ax
cmp dx, ALPHA_MIN
;----------------------------
jge alphaDigit
add dx, DECIMAL_ASCII
mov [bx], dl
jmp wasDecimalDigit
;--------------------
alphaDigit:
add dx, ALPHA_ASCII
mov [bx], dl
wasDecimalDigit:
;----------------------------
dec bx
shr ax, HEX_BINARY_LEN
cmp ax, 0000h
jne digitLoop
mov sp, bp
pop dx
pop ax
pop bx
pop bp
retn 6
endp hexToString
;----------------------------------------------------------------
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.