【问题标题】:mov instruction strange destination operandmov 指令奇怪的目标操作数
【发布时间】:2014-07-26 13:20:14
【问题描述】:

我正在尝试理解 Pintos 引导加载程序的代码,但在某行中有些东西让我觉得很奇怪。

addr32 movl %eax, init_ram_pages - LOADER_PHYS_BASE - 0x20000 这里的这一行应该是把4K页数放在头文件中定义的变量init_ram_pages中为:
extern uint32_t init_ram_pages;

我不明白为什么我们要从init_ram_pages 中减去这些值?在mov 的目标操作数中进行减法运算是什么意思?

更多详情:

在 %eax 中设置内存大小(以 4K 页为单位)的代码如下: (如果我的理解是正确的)

    movb $0x88, %ah
    int $0x15
    addl $1024, %eax    # Total kB memory
    cmp $0x10000, %eax  # Cap at 64 MB
    jbe 1f
    mov $0x10000, %eax
1:  shrl $2, %eax       # (shift right by two = divide by 4)
                # now eax contains the number of 4K pages I guess?

常量定义为:

/* Kernel virtual address at which all physical memory is mapped.
   Must be aligned on a 4 MB boundary. */
#define LOADER_PHYS_BASE 0xc0000000     /* 3 GB. */

编辑
变量本身在同一文件中定义如下:(在 .code32 之后的文件部分中)

#### Physical memory size in 4 kB pages.  This is exported to the rest
#### of the kernel.d
.globl init_ram_pages
init_ram_pages:
    .long 0

【问题讨论】:

    标签: memory assembly x86 cpu bootloader


    【解决方案1】:

    减法没有什么特别的,它只是一个简单的汇编或链接时间操作。在最终的二进制文件中,将呈现计算结果。

    我假设这是引导加载程序的实模式部分,但它是使用保护模式内存映射组装/链接的。调整可能会在汇编器为其生成代码的保护模式地址和 cpu 在运行此代码时实际使用的实模式地址之间进行转换。

    【讨论】:

    • 是的,这是在引导加载程序的实模式部分;但考虑到我设置了 .code16
    • 汇编器不知道您如何设置段寄存器(实模式和保护模式)。所以不能在两种地址之间进行转换。
    • (我已对答案进行了编辑,请检查)。因此,如果我现在正确理解,变量是在 .32 部分中声明的,它为它提供了一个受保护模式的 32 位地址,那么减法只是为了准确地指向它所在的位置,同时仍在运行实地址模式?
    • 只是为了扩展这个答案,看起来减去LOADER_PHYS_BASE 会将init_ram_pages 的地址从内核虚拟地址转换为物理地址。减去0x20000 将物理地址转换为DS 相对偏移量,其中实模式DS 值为0x2000
    • .code16 只是切换代码生成,不影响其他任何内容。没有单独的区域,实际上 16 位支持只是 gnu 工具中的一个螺栓固定的 hack。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2022-11-23
    • 2011-02-07
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多