我目前正在制作一个教程,演示如何从头开始构建操作系统。
在本教程的某些部分中,有一些汇编代码用于演示寻址。
代码只是尝试以4种不同的方式打印“X”。
该教程声称只有最后两种方式成功打印'X'。
当我在我的机器上尝试时,只有第三次尝试成功
以下是代码:
mov ah,0x0e
;first attempt
mov al,the_secret
int 0x10
;second attempt
mov al,[the_secret]
int 0x10
;third attempt
mov bx,the_secret
add bx,0x7c00 ; 0x7c00 is where bios loads our boot sector code
mov al,[bx]
int 0x10
;fourth attempt
mov al,[0x7c1e]
int 0x10
jmp $
the_secret:
db "X"
times 510 -( $ - $$ ) db 0
dw 0xaa55
现在,我理解为什么前两次尝试都失败了。
我相信最后两次尝试应该打印X
那么为什么第四次尝试无法打印'X'?
任何帮助将不胜感激
由于
答案 0 :(得分:3)
您需要了解细分以了解为什么一个或另一个可能会或可能不会打印X.
我不打算根据具体情况解释一切。相反,我会给你留下一些事实,一些反汇编和一些讨论。
首先,BIOS可以使用CS=7C0h
和IP=0
或CS=0
和IP=7C00h
启动您的启动器。两者都指向相同的实际地址:7C0h * 16 + 0
= 0 * 16 + 7C00h
= 7C00h
。
假设目前两种情况DS=CS
(无论是7C0h
还是0
),CPU都将拥有相同机器代码的两个不同视图之一你的bootsector:
IP instruction bytes instruction
00000000 B40E mov ah,0xe
00000002 B01E mov al,0x1e
00000004 CD10 int 0x10
00000006 A01E00 mov al,[0x1e]
00000009 CD10 int 0x10
0000000B BB1E00 mov bx,0x1e
0000000E 81C3007C add bx,0x7c00
00000012 8A07 mov al,[bx]
00000014 CD10 int 0x10
00000016 A01E7C mov al,[0x7c1e]
00000019 CD10 int 0x10
0000001B E9FDFF jmp word 0x1b
0000001E 58 pop ax ; this is your 'X'
...
或
IP instruction bytes instruction
00007C00 B40E mov ah,0xe
00007C02 B01E mov al,0x1e
00007C04 CD10 int 0x10
00007C06 A01E00 mov al,[0x1e]
00007C09 CD10 int 0x10
00007C0B BB1E00 mov bx,0x1e
00007C0E 81C3007C add bx,0x7c00
00007C12 8A07 mov al,[bx]
00007C14 CD10 int 0x10
00007C16 A01E7C mov al,[0x7c1e]
00007C19 CD10 int 0x10
00007C1B E9FDFF jmp word 0x7c1b
00007C1E 58 pop ax ; this is your 'X'
...
你现在可以清楚地看到为什么一些访问'X'的方法应该在一种情况下工作而不应该在另一种情况下工作,反之亦然。
现在,由于当您的bootsector开始执行时,BIOS不保证DS
中的任何特定值,您可能有DS≠CS
,这里有四种可能的情况:
CS=0
,DS=7C0h
- 访问X
的一些方法可行CS=7C0h
,DS=0
- 访问X
的其他一些方法也可以使用CS=0
,DS≠7C0h
- 访问X
的方法都不起作用CS=7C0h
,DS≠0
- 访问X
的方法都不起作用答案 1 :(得分:-2)
使用tasm而不是nasm 理论上它会起作用