NASM x86使用不存在的段寄存器7

时间:2016-07-28 06:54:49

标签: assembly x86 nasm

我目前正在x86程序集中编写一个简单程序,它将数据存储在任意内存地址并以十六进制形式打印到终端。它正在NASM 2.12.02中组装,我用bochs 2.6.8运行生成的垃圾箱。我编写了一个名为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

1 个答案:

答案 0 :(得分:7)

您必须将字符串数据移出代码,因为CPU在执行pusha指令后将执行字符串作为指令。您的字符串被解释为以下代码:

'01'  30 31  XOR BYTE PTR [BX+DI],DH
'23'  32 33  XOR DH,BYTE PTR [BP+DI]
'45'  34 35  XOR AL,35H
'67'  36:37  SS:AAA                   ;  Superfluous prefix
'89'  38 39  CMP BYTE PTR [BX+DI],BH
'A'   41     INC CX
'B'   42     INC DX
'C'   43     INC BX
'D'   44     INC SP
'E'   45     INC BP
'F'   46     INC SI

只要这些指令非常随机,就会产生随机行为。另请注意,堆栈指针已被修改,因此在程序退出时会出现更多混乱。