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

时间:2017-12-01 08:15:26

标签: assembly hex nasm x86-16 qemu

好的,在其他人将此问题标记为重复之前。让我明确指出,这更像是一个调试问题,而不是一个逻辑问题。据我所知,逻辑是正确的,因为如果我在每次操作后单独打印bx寄存器中的值,那么我得到正确的输出。问题是将结果存储在bx寄存器中应该更改它所持有的的内存位置。

所以,这些天我在NASM学习汇编语言。我正在关注pdf文档,要求您打印十六进制数字(将十六进制数字转换为十六进制数字,然后打印)。

我已编写代码,但似乎没有打印正确的十六进制数字。另一方面,如果我只是在以下代码片段中打印变量FINAL_ST而不调用INIT(这是十六进制数转换为十六进制字符串的开始),它可以正常工作并打印{{ 1}}。

我多次搜索但无济于事。

我发现gdb可用于调试0x0000程序,但当输出为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

1 个答案:

答案 0 :(得分:1)

您的问题出现在以下两行:

mov [bx], dx

这会将 DX 中的16位值移动到 BX 中指定的地址。由于x86是小端,因此在循环的每次迭代中都会将 DL 移动到[BX]并将 DH 移动到[BX+1]。由于 DH 在代码中始终为零,因此在每个字符写入FINAL_ST缓冲区后,NUL会终止字符串。

问题在于您真正希望使用 DL 中的字节更新 BX 指向的内存。将两行更改为:

mov [bx], dl

我有bootloader tips的Stackoverflow答案。提示#1是:

  

当BIOS跳转到您的代码时,您不能依赖具有有效或预期值的CS,DS,ES,SS,SP寄存器。应在引导加载程序启动时正确设置它们。您只能保证您的引导加载程序将从物理地址0x00007c00加载并运行,并且引导驱动器号将加载到DL寄存器中。

至少应将 DS 设置为零,因为您使用的是ORG(原点)0x7c00。在将控制权转移到引导加载程序之前,您不能假设BIOS将 DS 设置为零。它在 QEMU 中工作,因为它的BIOS恰好在 DS 中具有值0x0000。并非所有硬件和模拟器都能保证这一点。

相关问题