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
の「混合モード」のようなものだ。