我有一些x86 realmode汇编代码,它的行为与预期不完全一样。我相信这个问题与错误计算的jmp/呼叫偏移有关,但我可能弄错了。
以下是汇编语言代码:
[org 0x7c00]
mov ah, 0x0e
mov al, 'h'
int 0x10
mov al, 'e'
int 0x10
mov al, 'l'
int 0x10
mov al, 'l'
int 0x10
mov al, 'o'
int 0x10
mov al, '!'
;int 0x10
call print_char
;loop:
; jmp loop
mov si, mystring
call print_string
jmp $
; fill to 512 bytes
times 510 - ($ - $$) db 0
dw 0xAA55
; the address is stored in si
print_string:
pusha
; load character from si
mov al, [si]
cmp al, 0x00
jz print_string_end
call print_char ; print the char using the print_char function
inc si ; increment the string printing index si
print_string_end:
popa
ret
; print function: print a single character
; the character is stored in al
print_char:
pusha
mov ah, 0x0e
int 0x16
popa ; don't know what registers int 0x16 modifies
ret
mystring:
db "loading operating system",0x00
下面是大会:
objdump -D -b binary -m i8086 -M intel bootsector.bin
bootsector.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: b4 0e mov ah,0xe
2: b0 68 mov al,0x68
4: cd 10 int 0x10
6: b0 65 mov al,0x65
8: cd 10 int 0x10
a: b0 6c mov al,0x6c
c: cd 10 int 0x10
e: b0 6c mov al,0x6c
10: cd 10 int 0x10
12: b0 6f mov al,0x6f
14: cd 10 int 0x10
16: b0 21 mov al,0x21
18: e8 f2 01 call 0x20d
1b: be 14 7e mov si,0x7e14
1e: e8 df 01 call 0x200
21: eb fe jmp 0x21
...
1fb: 00 00 add BYTE PTR [bx+si],al
1fd: 00 55 aa add BYTE PTR [di-0x56],dl
200: 60 pusha
201: 8a 04 mov al,BYTE PTR [si]
203: 3c 00 cmp al,0x0
205: 74 04 je 0x20b
207: e8 03 00 call 0x20d
20a: 46 inc si
20b: 61 popa
20c: c3 ret
20d: 60 pusha
20e: b4 0e mov ah,0xe
210: cd 16 int 0x16
212: 61 popa
213: c3 ret
214: 6c ins BYTE PTR es:[di],dx
215: 6f outs dx,WORD PTR ds:[si]
216: 61 popa
217: 64 69 6e 67 20 6f imul bp,WORD PTR fs:[bp+0x67],0x6f20
21d: 70 65 jo 0x284
21f: 72 61 jb 0x282
221: 74 69 je 0x28c
223: 6e outs dx,BYTE PTR ds:[si]
224: 67 20 73 79 and BYTE PTR [ebx+0x79],dh
228: 73 74 jae 0x29e
22a: 65 6d gs ins WORD PTR es:[di],dx
...
文件是用
nasm bootsector.asm -f bin -o bootsector.bin
在线
1e
这是说明
call 0x200
。除非我误解了,否则这会将当前(指令指针+1)推到堆栈上,并跳到偏移量处执行代码
0x200
.这是记忆中的某个地方,它的起源是
0x7c00
,因此它似乎是一个不同于函数所在地址的地址
print_char
居住。
至少我认为这是正在发生的事情,但我可能是完全错误的,因为我是新来的。
还有——也许我不允许有一个超过512字节的文件作为引导扇区?