汇编:使用数据段寄存器(DS)
目前我正在学习 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开始的全局变量?或者我缺少什么内在的东西?
Currently I am in the midst of learning x86 assembly for fun, I'm love microcontroller programming, so I'm familiar with assembly.
Currently I've been searching high and low for the answer to this question, but can't seem to find it... the DS register, I know it's supposed to point to the global data in my program, but I don't know how it works exactly. I'm using NASM, and in most simple programs I see the following:
[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
and that works perfectly (even if I omit the bolded code), but how? Does the CPU automagically load the global variables starting at 0x0000? or is there something intrinsic here that I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当计算机处于实模式(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_Mode 和 http://www.internals.com/articles/protmode/realmode.htm< /a> 以及更多的地方。
顺便说一句,“msg”应该或多或少位于 0x7C11 地址。
When the computer is under real mode (the mode the CPU is at when the BIOS executes the bootloader), the method the CPU uses to calculate the address is very simple: Multiply segment register value by 16 (shift bits 4 positions to left), then add the offset.
For instance in an instruction like "mov ax, [0x1234]" the CPU would use "DS * 0x10 + 0x1234" as the effective address (the first term resolves to zero in your case.) When you have one like "mov ax, [BP+0x32]" then the CPU will use "SS * 0x10 + BP + 0x32". Note that now the CPU used a different segment register (the Stack Segment), and that is because when the BP register is used, the CPU assumes you wan't to access the stack by default (but you can override this by using [DS:BP + 0x32]).
More o less what I've explained and more can be found at http://wiki.osdev.org/Real_Mode and http://www.internals.com/articles/protmode/realmode.htm and lots of more places.
BTW, "msg" should be located more or less at 0x7C11 address.