汇编:使用数据段寄存器(DS)

时间:2011-02-04 23:24:35

标签: assembly x86 cpu-registers segment

目前我正在学习x86程序集以获得乐趣,我很喜欢单片机编程,所以我熟悉汇编。

目前我一直在寻找这个问题的答案的高低,但似乎无法找到它... DS寄存器,我知道它应该指向我程序中的全局数据,但是我不知道它是如何工作的。我正在使用NASM,在大多数简单的程序中,我看到以下内容:

[org 0x7C00]
[bits 16]  

main:
mov ax, 0x0000
mov ds, ax
mov al, [msg]  
mov ah, 0x0E  
mov bx, 0x0007  
int 0x10    
jmp $  

msg db 'X'

times 510-($-$$) db 0  
dw 0xAA55

并且完美无缺(即使我省略了粗体代码),但是如何? CPU是否自动加载从0x0000开始的全局变量?或者我有什么内在的东西,我错过了吗?

1 个答案:

答案 0 :(得分:13)

当计算机处于实模式时(BIOS执行引导加载程序时CPU所处的模式),CPU用于计算地址的方法非常简单:将段寄存器的值乘以16(将位4的位移到左),然后添加偏移。

例如在像“mov ax,[0x1234]”这样的指令中,CPU会使用“DS * 0x10 + 0x1234”作为有效地址(在你的情况下,第一项解析为零。)当你有一个像“ mov ax,[BP + 0x32]“然后CPU将使用”SS * 0x10 + BP + 0x32“。请注意,现在CPU使用了不同的段寄存器(堆栈段),这是因为当使用BP寄存器时,CPU假定您默认不访问堆栈(但您可以使用[DS]覆盖它:BP + 0x32])。

我在http://wiki.osdev.org/Real_Modehttp://www.internals.com/articles/protmode/realmode.htm以及更多地方可以找到更多或更少的内容。

BTW,“msg”应位于或多或少位于0x7C11地址。