Первый ряд печатает джонки. Не могу определить ошибку - PullRequest
4 голосов
/ 11 апреля 2019

here is the output

В первой строке печатаются мусорные блоки.

Я пытался переключать объекты со смещением, индексом и т. Д. Но первая строка всегда неверна, независимо от того, какая это строка.

    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

1 Ответ

4 голосов
/ 11 апреля 2019

Проблема в том, что вы выполняете данные в виде кода:

На компьютере ваша программа будет храниться в оперативной памяти. Это верно как для кода, так и для данных. В ОЗУ хранятся только числа в диапазоне от 0 до 255. ЦП не может различить код и данные.

Данные db ' 1 2 3 4 ... сохраняются как 0x20 0x20 ..., а инструкция and [bx+si],ah также сохраняется как 0x20 0x20 ....

Поскольку после mov ES, AX нет инструкции jmp, ЦПУ предполагает, что байты после mov es,ax представляют собой команду, которая должна быть выполнена (0x20 0x20 = and [bx+si],ah), а не данные.

Вероятно, что инструкции, выполняемые ЦП, приведут к сбою программы в таких случаях. В вашем случае, похоже, этого не происходит.

Однако в вашем случае последний байт данных равен 0x20. Это не полная инструкция x86, за ней следует инструкция mov si,offset nums, которая хранится как 0xbe xx xx. Процессор интерпретирует это как 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 машинный код использует большую часть доступного пространства кодирования, поэтому для данных, случайно декодированных как инструкция, нормально не попадать ни в какие недопустимые инструкции. (Особенно в 16/32-битном режиме.)

...