【发布时间】:2016-07-28 06:54:49
【问题描述】:
我目前正在用 x86 程序集编写一个简单的程序,该程序在任意内存地址获取数据并以十六进制形式将其打印到终端。它正在 NASM 2.12.02 中组装,我正在使用 bochs 2.6.8 运行生成的 bin。我编写了一个名为print_hex.asm 的例程,它使用db 来定义ascii 字符的索引,如下所示。
ascii_table: db "0123456789ABCDEF"
组装完整程序并运行结果时,同一行
(an increasing number)i[CPU0 ] MOV_EwSw: using of nonexisting segment register 7
再次打印到终端,前面是一个不断增加的数字。奇怪的是,如果我将行改为
ascii_table: db "0123456789ABC"
只需省略字符串的最后三个字母,它就可以正常工作(尽管组装的程序在尝试转换 D、E 或 F 的十六进制值时会出现运行时错误)
这里发生了什么?不能连续申报这么多数据吗? NASM 是在骚扰我吗?
编辑:完整源代码见下文。请注意,它仍在进行中,可能在其他地方存在逻辑错误。
print_hex: ; prints the value stored at bx in hex
pusha ; push all the local registers to the stack
ascii_table: ; define a table to store ascii characters for conversion
db "0123456789ABCDEF"
mov ah, 0x0e ; move 0x0e to the high byte of ax in preparation for a teletype interrupt
mov al, "0" ; move the ascii char 0 to the lower byte of ax
int 0x10 ; perform a teletype interrupt
mov al, "x" ; move the ascii char x to the lower byte of ax
int 0x10 ; perfrom a teletype interrupt
mov dx, 0 ; move 0 to dx in preparation for the loop
mov cx, 0 ; zero out cx
hex_print_loop_start:
mov cl, bl ; move bl to cl to isolate the lowest nybble of bx
add cl, ascii_table ; set the table offset with cx
mov al, cl ; get the value at the offset index of the table and store it in al for printing
int 0x10 ; perform a teletype interrupt
inc dx ; increment dx by one
shr bx, 1 ; shift bx right in preparation for reading the next character
cmp dx, byte 0x04 ; check if the loop has been performed 4 times
jl hex_print_loop_start ; if it hasn't been performed 4 times, jump to the beginning of the loop
popa ; restore local registers
ret ; return
【问题讨论】:
-
欢迎来到 Stack Overflow。请尽快阅读About 页面并访问描述How to Ask a Question 和How to create a Minimal, Complete, and Verifiable example 的链接。提供必要的详细信息,包括您的代码和相关错误(如果有),将让这里的每个人都能帮助您解决问题。
-
看起来你的代码试图“运行”字符串,即字符串的字节在运行时被解释为代码。您可以发布 print_hex 的代码吗?只需编辑您的问题并将其包含在内。
-
将
ascii_table移动到函数之后。数据就是代码。 -
您可以自己调试,方法是使用 bochs 的内置调试器单步执行您的代码,向您展示反汇编代码。
-
谢谢,以后我会更好地使用调试器