Проблема в том, что вы выполняете данные в виде кода:
На компьютере ваша программа будет храниться в оперативной памяти. Это верно как для кода, так и для данных. В ОЗУ хранятся только числа в диапазоне от 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-битном режиме.)