第一行是印刷垃圾。无法识别错误
The first row is printing junks. Cannot identify the error
第一行是印刷废品。
我尝试切换偏移量、索引等。但是无论字符串是什么,第一行总是错误的。
mov AX, 0b800h
mov ES, AX
nums db ' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 '
numsend label byte
;first row
MOV SI,OFFSET nums
MOV DI,160*4 +2 ;1st row,1st column, 2 cells per char
MOV AH, 07h
MOV CX,5*3;2 chars per digit, and 5 digit
row1:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row1
;second row
MOV SI,OFFSET nums+15 ;point to the beginning of '_6 _7 _8 _9 10' from nums array
MOV DI,160*5 +2 ;2nd row,1st column, 2 cells per char
MOV AH, 07h
MOV CX,5*3 ;2 chars per digit, and 4 digit
row2:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row2
;third row
MOV SI,OFFSET nums+30 ;point to the beginning of '11 12 13 14 15' from nums array
MOV DI,160*6 + 2*1 ;3rd row,1stcolumn,2 cells per char
MOV AH, 07h
MOV CX,5*3 ;2 chars per digit, and 4 digit
row3:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row3
;fourth row
MOV SI,OFFSET nums+45 ;point to the beginning of ' 16 17 18 19 ' from nums array
MOV DI,160*7 + 2*1 ;4th row,1stcolumn,2 cells per char
MOV AH, 07h
MOV CX,5*3 ;2 chars per digit, and 4 digit
row4:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row4
我预计:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19
但我总是得到:
随机 ascii 值(第一行)
6 7 8 9 10
11 12 13 14 15
16 17 18 19
问题是您将数据作为代码执行:
在计算机中,您的程序将存储在RAM中。对于代码和数据都是如此。 RAM 只存储 0 到 255 范围内的数字。CPU 无法区分代码和数据。
数据db ' 1 2 3 4 ...
存储为0x20 0x20 ...
,指令and [bx+si],ah
也存储为0x20 0x20 ...
。
因为mov ES, AX
之后没有jmp
指令,所以CPU假设mov es,ax
之后的字节代表要执行的指令(0x20 0x20
= and [bx+si],ah
) 而不是数据。
在这种情况下,CPU执行的指令很可能会导致程序崩溃。在你的情况下,这似乎不会发生。
但是,在您的情况下,数据的最后一个字节是 0x20
。这不是完整的 x86 指令,它后面是指令 mov si,offset nums
,存储为 0xbe xx xx
。 CPU 会将其解释为 0x20 0xbe xx xx
即 and [bp+nums],bh
.
因此 si
寄存器不会被设置。
用 NASM 将文件的第一部分(在移植语法之后)组装成平面二进制文件并用 ndisasm
反汇编,我们得到:
address hexdump disassembly
00000000 B800B8 mov ax,0xb800
00000003 8EC0 mov es,ax
00000005 2020 and [bx+si],ah ; two ASCII spaces = 0x2020
00000007 3120 xor [bx+si],sp
00000009 2032 and [bp+si],dh
0000000B 2020 and [bx+si],ah
0000000D 3320 xor sp,[bx+si]
0000000F 2034 and [si],dh
00000011 2020 and [bx+si],ah
00000013 352020 xor ax,0x2020
00000016 362020 and [ss:bx+si],ah
00000019 37 aaa
0000001A 2020 and [bx+si],ah
0000001C 3820 cmp [bx+si],ah
0000001E 2039 and [bx+di],bh
00000020 2031 and [bx+di],dh
00000022 3020 xor [bx+si],ah
00000024 3131 xor [bx+di],si
00000026 2031 and [bx+di],dh
00000028 3220 xor ah,[bx+si]
0000002A 3133 xor [bp+di],si
0000002C 2031 and [bx+di],dh
0000002E 3420 xor al,0x20
00000030 3135 xor [di],si
00000032 2031 and [bx+di],dh
00000034 362031 and [ss:bx+di],dh
00000037 37 aaa
00000038 2031 and [bx+di],dh
0000003A 3820 cmp [bx+si],ah
0000003C 3139 xor [bx+di],di
0000003E 2020 and [bx+si],ah
00000040 20BE0500 and [bp+0x5],bh ; 0x20 is the last space,
; BE imm16 is the mov-to-SI
00000044 BF8202 mov di,0x282 ; decoding happens to line up with this instruction
00000047 B407 mov ah,0x7
00000049 B90F00 mov cx,0xf
所以有很多内存目标指令,但显然 BX
、SI
、DI
、BP
以及它们的各种组合并没有指向任何难以销毁的地方。
x86 机器码使用了大部分可用的编码 space,因此数据被意外解码为指令时不会遇到任何非法指令是正常的。 (尤其是在 16 / 32 位模式下。)
第一行是印刷废品。
我尝试切换偏移量、索引等。但是无论字符串是什么,第一行总是错误的。
mov AX, 0b800h
mov ES, AX
nums db ' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 '
numsend label byte
;first row
MOV SI,OFFSET nums
MOV DI,160*4 +2 ;1st row,1st column, 2 cells per char
MOV AH, 07h
MOV CX,5*3;2 chars per digit, and 5 digit
row1:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row1
;second row
MOV SI,OFFSET nums+15 ;point to the beginning of '_6 _7 _8 _9 10' from nums array
MOV DI,160*5 +2 ;2nd row,1st column, 2 cells per char
MOV AH, 07h
MOV CX,5*3 ;2 chars per digit, and 4 digit
row2:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row2
;third row
MOV SI,OFFSET nums+30 ;point to the beginning of '11 12 13 14 15' from nums array
MOV DI,160*6 + 2*1 ;3rd row,1stcolumn,2 cells per char
MOV AH, 07h
MOV CX,5*3 ;2 chars per digit, and 4 digit
row3:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row3
;fourth row
MOV SI,OFFSET nums+45 ;point to the beginning of ' 16 17 18 19 ' from nums array
MOV DI,160*7 + 2*1 ;4th row,1stcolumn,2 cells per char
MOV AH, 07h
MOV CX,5*3 ;2 chars per digit, and 4 digit
row4:
MOV AL,[SI]
MOV ES:[DI],AX
INC SI
ADD DI,2
LOOP row4
我预计:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19
但我总是得到: 随机 ascii 值(第一行)
6 7 8 9 10
11 12 13 14 15
16 17 18 19
问题是您将数据作为代码执行:
在计算机中,您的程序将存储在RAM中。对于代码和数据都是如此。 RAM 只存储 0 到 255 范围内的数字。CPU 无法区分代码和数据。
数据db ' 1 2 3 4 ...
存储为0x20 0x20 ...
,指令and [bx+si],ah
也存储为0x20 0x20 ...
。
因为mov ES, AX
之后没有jmp
指令,所以CPU假设mov es,ax
之后的字节代表要执行的指令(0x20 0x20
= and [bx+si],ah
) 而不是数据。
在这种情况下,CPU执行的指令很可能会导致程序崩溃。在你的情况下,这似乎不会发生。
但是,在您的情况下,数据的最后一个字节是 0x20
。这不是完整的 x86 指令,它后面是指令 mov si,offset nums
,存储为 0xbe xx xx
。 CPU 会将其解释为 0x20 0xbe xx xx
即 and [bp+nums],bh
.
因此 si
寄存器不会被设置。
用 NASM 将文件的第一部分(在移植语法之后)组装成平面二进制文件并用 ndisasm
反汇编,我们得到:
address hexdump disassembly
00000000 B800B8 mov ax,0xb800
00000003 8EC0 mov es,ax
00000005 2020 and [bx+si],ah ; two ASCII spaces = 0x2020
00000007 3120 xor [bx+si],sp
00000009 2032 and [bp+si],dh
0000000B 2020 and [bx+si],ah
0000000D 3320 xor sp,[bx+si]
0000000F 2034 and [si],dh
00000011 2020 and [bx+si],ah
00000013 352020 xor ax,0x2020
00000016 362020 and [ss:bx+si],ah
00000019 37 aaa
0000001A 2020 and [bx+si],ah
0000001C 3820 cmp [bx+si],ah
0000001E 2039 and [bx+di],bh
00000020 2031 and [bx+di],dh
00000022 3020 xor [bx+si],ah
00000024 3131 xor [bx+di],si
00000026 2031 and [bx+di],dh
00000028 3220 xor ah,[bx+si]
0000002A 3133 xor [bp+di],si
0000002C 2031 and [bx+di],dh
0000002E 3420 xor al,0x20
00000030 3135 xor [di],si
00000032 2031 and [bx+di],dh
00000034 362031 and [ss:bx+di],dh
00000037 37 aaa
00000038 2031 and [bx+di],dh
0000003A 3820 cmp [bx+si],ah
0000003C 3139 xor [bx+di],di
0000003E 2020 and [bx+si],ah
00000040 20BE0500 and [bp+0x5],bh ; 0x20 is the last space,
; BE imm16 is the mov-to-SI
00000044 BF8202 mov di,0x282 ; decoding happens to line up with this instruction
00000047 B407 mov ah,0x7
00000049 B90F00 mov cx,0xf
所以有很多内存目标指令,但显然 BX
、SI
、DI
、BP
以及它们的各种组合并没有指向任何难以销毁的地方。
x86 机器码使用了大部分可用的编码 space,因此数据被意外解码为指令时不会遇到任何非法指令是正常的。 (尤其是在 16 / 32 位模式下。)