操作系统的抽象和裸机?

时间:2017-12-04 10:07:53

标签: x86 computer-science cpu-architecture

如果我有一个CPU并且我编写了一个程序并且我想存储一个值(将一个值从寄存器复制到内存(RAM))那么我会在CPU的指令集中使用一个指令(假设这是一个x86 CPU)这样做?

第二个问题,x86指令集中的指令是否在RAM中的特定地址设置一个名为MOV的值?

第三个问题。 BIOS,UEFI,内核和引导加载程序都使用x86指令集中的MOV指令(将值(如10)分配给RAM中的特定地址)对吗?

第四个问题。在OS(具有内核(如Linux))环境中运行的程序在请求它时不使用MOV指令来获取分配的一块内存,而是要求内核代表它们执行此操作?

第五个问题。我在第四个问题中描述的是一个系统调用(当一个在OS环境中运行的程序要求内核代表它做某事时(在这种情况下给它一些内存))?

1 个答案:

答案 0 :(得分:0)

0.我认为你对汇编语言知之甚少,甚至没有提出一个合理的问题,这个问题确实填补了你所遗漏的任何差距,但我试图回答你的问题。我真的不确定你真正想知道什么。

也许请查看Matt Godbolt的CppCon2017演讲:“What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid”,了解x86 asm的初学者介绍。

但我认为你错过了一些关于堆栈/堆/静态存储位置的概念。见Stack, Static, and Heap in C++

  1. 是的,最常见的x86存储指令是mov。例如mov dword [rdi], 10。或者在指令中使用绝对地址编码,mov dword [my_static_32_bit_location], 10

  2. 奇怪的具体。您可以编写一个没有任何静态数据的引导加载程序。所有的mov-immediate指令都将使用寄存器目的地。

  3. mov不会分配保留内存。在OS下运行的程序可以具有静态数据。例如考虑这个C函数:

    unsigned LCG_rand() {
        static unsigned seed = 0x1234;
        seed = seed * 0x5677 + 0x7723;  // Linear Congruential Generator with badly chosen coefficients I just made up
        return seed;                    // mod type-width is implicit
    }
    

    gcc7.2定位x86-64 Linux将其编译为(Godbolt compiler explorer)

    LCG_rand:
        imul    eax, DWORD PTR seed.2294[rip], 22135    # eax = load(seed) * 22135
        add     eax, 30499                              # eax += 30499
        mov     DWORD PTR seed.2294[rip], eax           # store the old value back to memory.
        ret
    
    .data            # static read-write data goes in the .data section
    .align 4
    seed.2294:       # label which the compiler uses to refer to it.
        .long   4660
    

    .data部分包含具有非零初始值设定项的静态读写数据。初始值按字面存储在可执行文件中。它链接到可执行文件的数据段。运行它时,可执行文件的数据段将映射到进程的内存空间,具有读/写权限,写时复制(私有)。 (因此,将数据写入内存不会更新磁盘上的数据,就像使用mmap MAP_SHARED一样。)

    这些地址是链接时常量,因此程序可以直接使用它。 (在上面的代码中,该函数使用PC相对寻址,但也支持绝对。You may have to use -no-pie on some gcc setups, though.

    完全相同的机器代码在裸机环境中可以正常工作,即使禁用了分页,因此您使用的地址是物理地址,而不是通常的虚拟地址,它们允许每个进程有自己的记忆观。 (呃,但你可能不得不处于16位或32位模式,我忘了如果x86-64长模式甚至可以禁用分页。)

  4. 是肯定的。有关 用户空间进程如何进行系统调用的详细信息,请参阅What are the calling conventions for UNIX & Linux system calls on i386 and x86-64