FromNandの日記

自分的備忘録

C言語ではDS, ES, SSを同じ値にしなければならないのはなぜか?

そういう前提を置くことでコンパイラ機械語を生成するときにラクできるから、ということらしいです。
まぁ、DSやES、SSをうまく扱うのは難しそう。


ここで実際の確認コードをある掲示板で見つけたので貼っておく。

#include<stdio.h>

int main(void)
{
    int i;
    int *p = &i;
    i = 1; /* コンパイラはこの代入文でSSを使うようにコンパイルする */
    *p = 2; /* pにはiの番地が入っているので、iはこれで2になるはず */
        /* ↑コンパイラはこの代入文でDSを使うようにコンパイルする */
    if (i == 1) {
        printf("a\n");
    } else {
        printf("b\n");
    }
    return 0;
}


アセンブラはこちら。
espやebpの間接アドレス指定はssを参照するが、「eax, ecx, edx, ebx, esi, edi」などのレジスタはdsを参照するのでこういった動作の違いがおきてしまうらしい。

0000056d <main>:
 56d:   8d 4c 24 04             lea    0x4(%esp),%ecx
 571:   83 e4 f0                and    $0xfffffff0,%esp
 574:   ff 71 fc                pushl  -0x4(%ecx)
 577:   55                      push   %ebp
 578:   89 e5                   mov    %esp,%ebp
 57a:   53                      push   %ebx
 57b:   51                      push   %ecx
 57c:   83 ec 10                sub    $0x10,%esp
 57f:   e8 79 00 00 00          call   5fd <__x86.get_pc_thunk.ax>
 584:   05 50 1a 00 00          add    $0x1a50,%eax
 589:   65 8b 0d 14 00 00 00    mov    %gs:0x14,%ecx
 590:   89 4d f4                mov    %ecx,-0xc(%ebp)
 593:   31 c9                   xor    %ecx,%ecx
 595:   8d 55 ec                lea    -0x14(%ebp),%edx
 598:   89 55 f0                mov    %edx,-0x10(%ebp)
 59b:   c7 45 ec 01 00 00 00    movl   $0x1,-0x14(%ebp)
 5a2:   8b 55 f0                mov    -0x10(%ebp),%edx
 5a5:   c7 02 02 00 00 00       movl   $0x2,(%edx)
 5ab:   8b 55 ec                mov    -0x14(%ebp),%edx
 5ae:   83 fa 01                cmp    $0x1,%edx
 5b1:   75 16                   jne    5c9 <main+0x5c>
 5b3:   83 ec 0c                sub    $0xc,%esp
 5b6:   8d 90 dc e6 ff ff       lea    -0x1924(%eax),%edx
 5bc:   52                      push   %edx
 5bd:   89 c3                   mov    %eax,%ebx
 5bf:   e8 3c fe ff ff          call   400 <puts@plt>
 5c4:   83 c4 10                add    $0x10,%esp
 5c7:   eb 14                   jmp    5dd <main+0x70>
 5c9:   83 ec 0c                sub    $0xc,%esp
 5cc:   8d 90 de e6 ff ff       lea    -0x1922(%eax),%edx
 5d2:   52                      push   %edx
 5d3:   89 c3                   mov    %eax,%ebx
 5d5:   e8 26 fe ff ff          call   400 <puts@plt>
 5da:   83 c4 10                add    $0x10,%esp
 5dd:   b8 00 00 00 00          mov    $0x0,%eax
 5e2:   8b 4d f4                mov    -0xc(%ebp),%ecx
 5e5:   65 33 0d 14 00 00 00    xor    %gs:0x14,%ecx
 5ec:   74 05                   je     5f3 <main+0x86>
 5ee:   e8 8d 00 00 00          call   680 <__stack_chk_fail_local>
 5f3:   8d 65 f8                lea    -0x8(%ebp),%esp
 5f6:   59                      pop    %ecx
 5f7:   5b                      pop    %ebx
 5f8:   5d                      pop    %ebp
 5f9:   8d 61 fc                lea    -0x4(%ecx),%esp
 5fc:   c3                      ret