らんだむな記憶

blogというものを体験してみようか!的なー

みかん日記 (6)

p. 89 の「ポインタとアセンブリ言語」についてやはり少し見ておく。

[foo.cpp]

#include <cstdint>

void foo()
{
    int i = 42;
    int* p = &i;
    int r1 = *p;
    *p = 1;
    int r2 = i;
    uintptr_t addr = reinterpret_cast<uintptr_t>(p);
    int* q = reinterpret_cast<int*>(addr);
}

を使って、

clang++ -O0 -S -o foo.s foo.cpp

して内容を見てみる。(g++ だとまた微妙に違ったので今回はなかったことにする)

・・・が実はこれだと書籍の表示と違って読み比べがしんどいので本に書いてある通りに Intel 形式でアセンブラを吐かせる。

clang++ -O0 -S -mllvm -x86-asm-syntax=intel -o foo.s foo.cpp

すると

 .text
    .intel_syntax noprefix
    .file "foo.cpp"
    .globl    _Z3foov                 # -- Begin function _Z3foov
    .p2align  4, 0x90
    .type _Z3foov,@function
_Z3foov:                                # @_Z3foov
    .cfi_startproc
# %bb.0:
    push rbp
    .cfi_def_cfa_offset 16
    .cfi_offset rbp, -16
    mov  rbp, rsp
    .cfi_def_cfa_register rbp
    mov  dword ptr [rbp - 4], 42
    lea  rax, [rbp - 4]
    mov  qword ptr [rbp - 16], rax
    mov  rax, qword ptr [rbp - 16]
    mov  ecx, dword ptr [rax]
    mov  dword ptr [rbp - 20], ecx
    mov  rax, qword ptr [rbp - 16]
    mov  dword ptr [rax], 1
    mov  ecx, dword ptr [rbp - 4]
    mov  dword ptr [rbp - 24], ecx
    mov  rax, qword ptr [rbp - 16]
    mov  qword ptr [rbp - 32], rax
    mov  rax, qword ptr [rbp - 32]
    mov  qword ptr [rbp - 40], rax
    pop  rbp
    .cfi_def_cfa rsp, 8
    ret
.Lfunc_end0:
    .size _Z3foov, .Lfunc_end0-_Z3foov
    .cfi_endproc
                                        # -- End function

    .ident    "clang version 7.0.0-3~ubuntu0.18.04.1 (tags/RELEASE_700/final)"
    .section  ".note.GNU-stack","",@progbits
    .addrsig
    .addrsig_sym _Z3foov

で、書籍と同じ内容になる。
ソースコードとも比較したいので、一旦コンパイルしきって objdump で眺めることにする。
つらさを緩和するために、デバッグ情報を付与させてコンパイルすべき -g を追加する。tldr objdump の結果は・・・今回はちょっと情報量が足りないので・・・man objdump の結果を参考に・・・するわけなく、gg って調べて以下のようにする。こちらも Intel 記法で表示させる。

clang++ -O0 -c -g -o foo.o foo.cpp
objdump  -CxS -M intel --prefix-addresses foo.o

すると

#include <cstdint>

void foo()
{
0000000000000000 <foo()> push   rbp
0000000000000001 <foo()+0x1> mov    rbp,rsp
    int i = 42;
0000000000000004 <foo()+0x4> mov    DWORD PTR [rbp-0x4],0x2a
    int* p = &i;
000000000000000b <foo()+0xb> lea    rax,[rbp-0x4]
000000000000000f <foo()+0xf> mov    QWORD PTR [rbp-0x10],rax
    int r1 = *p;
0000000000000013 <foo()+0x13> mov    rax,QWORD PTR [rbp-0x10]
0000000000000017 <foo()+0x17> mov    ecx,DWORD PTR [rax]
0000000000000019 <foo()+0x19> mov    DWORD PTR [rbp-0x14],ecx
    *p = 1;
000000000000001c <foo()+0x1c> mov    rax,QWORD PTR [rbp-0x10]
0000000000000020 <foo()+0x20> mov    DWORD PTR [rax],0x1
    int r2 = i;
0000000000000026 <foo()+0x26> mov    ecx,DWORD PTR [rbp-0x4]
0000000000000029 <foo()+0x29> mov    DWORD PTR [rbp-0x18],ecx
    uintptr_t addr = reinterpret_cast<uintptr_t>(p);
000000000000002c <foo()+0x2c> mov    rax,QWORD PTR [rbp-0x10]
0000000000000030 <foo()+0x30> mov    QWORD PTR [rbp-0x20],rax
    int* q = reinterpret_cast<int*>(addr);
0000000000000034 <foo()+0x34> mov    rax,QWORD PTR [rbp-0x20]
0000000000000038 <foo()+0x38> mov    QWORD PTR [rbp-0x28],rax
}
000000000000003c <foo()+0x3c> pop    rbp
000000000000003d <foo()+0x3d> ret

のように見えるようになるので相当に優しい世界になる。Visual Studio の「混合モード」のようなものだ。