繁体   English   中英

将十六进制数转换为汇编语言中的十六进制字符串(NASM)(调试)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM