Я ударился головой о стену, пытаясь понять , почему следующий сборник неправильно сбросил содержимое «HELLO_WORLD».Сборка (x86): <label> db 'string', 0 не выполняется, если нет инструкции по прыжку
; Explicitly set 16-bit
[ BITS 16 ]
[ ORG 0x7C00 ]
; Create label for hello world string terminated by null.
HELLO_WORLD db 'hello world', 0
start:
; Move address of HELLO_WORLD into si
mov SI, HELLO_WORLD
call print_string
; Continue until the end of time
jmp $
print_string:
loop:
; Retrieve value stored in address at si
mov al, [SI]
mov ah, 0x0E
cmp al, 0
; Finish execution after hitting null terminator
je return
INT 0x10
; Increment contents of si (address)
inc SI
jmp loop
return:
ret
; boot loader length *must* be 512 bytes.
times 510-($-$$) db 0
dw 0xAA55
В конце концов, я обнаружил, что если мы не будем выполнять (сделать это не код) наклейку, то он функционирует правильно.
jmp start
HELLO_WORLD db 'hello world',0
Часть I найти наиболее запутанным, глядя на шестнадцатеричного дампа hello_world еще в двоичном (в начале - и кажется, нет никакого различия его типа).
кошка nojmp_boot.out
00000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 00 be 00 7c e8 |hello world...|.|
00000010 02 00 eb fe 8a 04 b4 0e 3c 00 74 05 cd 10 46 eb |........<.t...F.|
00000020 f3 c3 eb e8 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
кошка jmpboot.out
00000000 eb 22 68 65 6c 6c 6f 20 77 6f 72 6c 64 00 be 02 |."hello world...|
00000010 7c e8 02 00 eb fe 8a 04 b4 0e 3c 00 74 05 cd 10 ||.........<.t...|
00000020 46 eb f3 c3 eb e8 00 00 00 00 00 00 00 00 00 00 |F...............|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
Осматривая первые два байта, мы можем видеть 'e8 22' является shortjump для решения 22 (http://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf).
Мой вопрос:
Почему мы не можем иметь «hello_world» как часть выполнения программы, насколько я был обеспокоен, что не было никакого различия между кодом и данными?
Я использую следующие для компиляции:
nasm -f bin -o boot.bin boot.asm && if [ $(stat -c "%s" boot.bin) -ne 512 ]; then x; fi && qemu-system-x86_64 boot.bin
Большое спасибо user3144770. Из любопытства, есть ли какая-либо причина, по которой я не могу взять адрес HELLO_WORLD (так как это ярлык) и поместить его в регистр, который позже будет повторяться? (Я думаю, байтовый поток) –
'mov si, HELLO_WORLD' уже делает то, что вы просите.(NASM синтаксис) –
Проблема заключается в том, если я тогда попробуйте использовать: мов др, [SI] Он заканчивается на КСС ал, 0 JE возвратного –