DS段寄存器采用32位架构

Myk*_*III 0 c linux assembly nasm disassembly

我一直在研究如何通过反汇编C代码在x86架构中处理浮点运算.使用的操作系统是64位Linux,而代码是为32位机器编译的.

这是C源代码:

#include <stdio.h>
#include <float.h>

int main(int argc, char *argv[])
{
    float a, b;
    float c, d;

    printf("%u\n",sizeof(float));

    a = FLT_MAX;
    b = 5;

    c = a / b;
    d = (float) a / (float) b;

    printf("%f %f \n",c,d);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是32位exe的主要功能的反汇编版本:

 804841c:   55                      push   ebp
 804841d:   89 e5                   mov    ebp,esp
 804841f:   83 e4 f0                and    esp,0xfffffff0
 8048422:   83 ec 30                sub    esp,0x30
 8048425:   c7 44 24 04 04 00 00    mov    DWORD PTR [esp+0x4],0x4
 804842c:   00 
 804842d:   c7 04 24 20 85 04 08    mov    DWORD PTR [esp],0x8048520
 8048434:   e8 b7 fe ff ff          call   80482f0 <printf@plt>
 8048439:   a1 2c 85 04 08          mov    eax,ds:0x804852c
 804843e:   89 44 24 2c             mov    DWORD PTR [esp+0x2c],eax
 8048442:   a1 30 85 04 08          mov    eax,ds:0x8048530
 8048447:   89 44 24 28             mov    DWORD PTR [esp+0x28],eax
 804844b:   d9 44 24 2c             fld    DWORD PTR [esp+0x2c]
 804844f:   d8 74 24 28             fdiv   DWORD PTR [esp+0x28]
 8048453:   d9 5c 24 24             fstp   DWORD PTR [esp+0x24]
 8048457:   d9 44 24 2c             fld    DWORD PTR [esp+0x2c]
 804845b:   d8 74 24 28             fdiv   DWORD PTR [esp+0x28]
 804845f:   d9 5c 24 20             fstp   DWORD PTR [esp+0x20]
 8048463:   d9 44 24 20             fld    DWORD PTR [esp+0x20]
 8048467:   d9 44 24 24             fld    DWORD PTR [esp+0x24]
 804846b:   d9 c9                   fxch   st(1)
 804846d:   dd 5c 24 0c             fstp   QWORD PTR [esp+0xc]
 8048471:   dd 5c 24 04             fstp   QWORD PTR [esp+0x4]
 8048475:   c7 04 24 24 85 04 08    mov    DWORD PTR [esp],0x8048524
 804847c:   e8 6f fe ff ff          call   80482f0 <printf@plt>
 8048481:   b8 00 00 00 00          mov    eax,0x0
 8048486:   c9                      leave  
 8048487:   c3                      ret    
 8048488:   66 90                   xchg   ax,ax
 804848a:   66 90                   xchg   ax,ax
 804848c:   66 90                   xchg   ax,ax
 804848e:   66 90                   xchg   ax,ax
Run Code Online (Sandbox Code Playgroud)

我理解的是浮点值传输到寄存器的行.特别:

mov    eax,ds:0x804852c  
mov    eax,ds:0x8048530
Run Code Online (Sandbox Code Playgroud)

根据我的理解,指令应分别等于mov eax,[0x804852c]和mov eax,[0x8048530],因为在32位模式下,ds寄存器通常指向整个32位空间,通常为0.但是当我检查寄存器时值不是0.它有值

ds             0x2b
Run Code Online (Sandbox Code Playgroud)

鉴于该值,不应该计算

0x2b *0x10 + 0x8048520
Run Code Online (Sandbox Code Playgroud)

但是,浮点数存储在0x8048520和0x8048530中,就像DS中的值为0一样.任何人都可以向我解释为什么会这样?

Sev*_*yev 5

处于保护模式的DS完全不同.它不是线性地址的移位部分,就像在实模式中一样,它是包含段的基地址的段表的索引.OS内核维护段表,userland代码不能.

也就是说,忽略ds:前缀.反汇编程序明确地拼写出默认行为,就是这样.默认情况下,此命令使用DS作为选择器; 所以反汇编者认为它会提到.操作系统会将DS初始化为对过程有意义的东西,并且在整个过程中将使用相同的DS值.