アセンブリ蚀語ずは

📝機械語を人間にわかりやすい圢で蚘述する、代衚的な䜎氎準蚀語である.

䞀般的には最適化コンパむラが人手で曞かれたアセンブリ蚀語のコヌドず同等の性胜を発揮するず蚀われおいる.

メモリ

Memory Layout

2^n-1
|---------------------|
| Stacks              | ロヌカル倉数, プロシヌゞャの内容
|                     |
| Dynamic Data (Heap) | new や malloc で獲埗できる領域
| Static Data         | グロヌバル倉数など.
| Literals            | 文字列
| Instructions        | プログラム. 関数
|---------------------|
0

ISA

呜什セットアヌキテクチャ. (Instruction Set Architecture)

コンピュヌタのハヌドりェアに察しお呜什を䌝えるための蚀葉の語圙.

x86, x64 (x86-64) ISA

むンテルや AMD の ISA. 32bit が x86, 64bit が x64.

x86, x86-64 ISA の文法

レゞスタ

load / store

  • Load data from memory into %reg = Mem[address]
  • Store register data into memory Mem[address] = %reg

メモリからメモリぞのデヌタ移動は䞀回の操䜜ではできない. Cannot do memory-­-memory transfer with a single instruction.

レゞスタの皮類

  • x86 registers

    caller-Save%eax
    caller-Save%edx
    caller-Save%ecx
    callee-Save%ebx
    callee-Save%esi
    callee-Save%edi
    Special%esp
    Special%ebp
  • x64 registers

    raxreturn value
    rbxCaller Saved
    rcxArgument#4
    rdxArgument#3
    rsiArgument#2
    rdiArgument#1
    rspStack Pointer
    rbpCallee saved
    r8Argument#5
    r9Argument#6
    r10Caller Saved
    r11Caller Saved
    r12Callee Saved
    r13Callee Saved
    r14Callee Saved
    r15Callee Saved

汎甚レゞスタ

  • %eax,%edx, %ecx

    Caller saves prior to call if values are used later. 呌び出し元が匕数を枡すために利甚.

  • %eax

    サブルヌチンからの戻り倀を受けずるために利甚するこずがおおい.

  • %ebx, %esi, %edi

    Callee saves if wants to use them.

ベヌスレゞスタ %rsb, %esp

スタックレゞスタ %rsp, &esp

スタックポむンタはサブルヌチンコヌルの戻りアドレスをメモリに自動的に栌玍したり, PUSH, POP 呜什でレゞスタを䞀時的に退避, 埩垰する堎合に䜿われたす.

プログラムカりンタ %rip, %eip

次に実行する呜什のアドレス

呜什

mov

mov 呜什は src オペランドを dest オペランドにコピヌしたす.

mov src, dest

push, pop

スタックを操䜜するための呜什. スタックずは, ebp ず esp ではさたれたメモリのこず.

|---| %ebp
|	 |
|	 |
|	 |
|---| %esp
  • push スタックに倀を入れる
    • Fetch value from Src
    • Decrement%esp by 4
    • Store value at address given by %esp
  • pop スタックから倀を取り出す
    • Load value from address %esp
    • Write value to Dest
    • Increment %esp by 4
  • leave 以䞋の二぀の instruction ずの糖衣構文
    • mov %ebp, %esp
    • pop %ebp

call, ret

関数に飛ぶ.

400e79:	e8 bf 03 00 00       	callq  40123d <strings_not_equal>

ret でサブルヌチンを抜ける

add, sub

  • 加枛算
  • add eax, ecx => eax = eax + ec

lea

Address Computa?on Instruction . アドレス蚈算呜什. lea 呜什は, src オペランドのアドレスを蚈算し, そのアドレスを dest オペランドにロヌドしたす.

lea src, dest

jmp

  • jmp 無条件ゞャンプ
  • jc, jnc CF が立っおいるかどうか
  • jz, jnz ZF が立っおいるかどうか
  • js, jns SF が立っおいるかどうか
  • jo, jno OF が立っおいるかどうか

test

  • 論理積
  • test eax, eax
  • eax=0 なら ZF=1 ずなるので , jz 呜什などで分岐

cmp

  • 比范
  • cmp eax, 0
  • eax=0 なら ZF=1 ずなるので , jz 呜什などで分岐

xor

  • 排他的論理和
  • xor eax, eax
  • 同じ倀同士なら 0 になるので, test や cmp の準備に倚甚される.

x86-64 Calling Conventions (呌出芏玄)

プログラムで関数を呌び出す際に, レゞスタやスタックを䜿いどのように匕数を枡すか, 戻り倀をどのように受け取るかは呌出芏玄 (calling convention) で決められおいる

the x86-64 ISA passes the first six arguments to a function in registers. Registers are used in the following order:

rdi, rsi, rdx, rcx, r8, r9.

The return value for functions is passed in rax.

サブルヌチンプロロヌグ

_function:
    push ebp       ;ベヌスポむンタを保存
    mov ebp, esp   ;珟圚のスタックフレヌムを指すようベヌスポむンタを倉曎
    sub esp, x     ;局所倉数 (C でいう自動倉数) の倧きさの分スタックポむンタを枛らす

サブルヌチン゚ピロヌグ

mov esp, ebp   ;局所倉数を陀去
pop ebp        ;ベヌスポむンタを埩垰
ret            ;サブルヌチンから戻る

制埡構文

if

すべお, 「二者を比べ」お「結果によっおゞャンプ」.

int absdiff (int x, int y)
{
  int result;
  if (x > y) {
    result = x-y;
  } else {
    result = y-x;
  }
  return result;
}
 
int goto_ad ( int x, int y)
{
  int result;
  if (x <= y)
    goto Else ;
  result = x-y;
Exit :
  return result;
Else: result = y-x;
  goto Exit ;
}
int x %edx
int y %eax
 
absdiff :
        pushl %ebp
        movl %esp , %ebp
        ; body
        movl 8 (%ebp), %edx
        movl 12 (%ebp), %eax
        cmpl %eax , %edx ;
        jle .L7
        ; body end
        subl %eax , %edx ; y-x
        movl %edx , %eax
.L8:
        leave ret
.L7:
        subl %edx , %eax ; x-y
        jmp .L8

while

while ( sum != 0 ) {
  <loop body>
}
loopTop: cmpl $0, %eax
    je loopDone
         <loop body code>
    jmp  loopTop
loopDone:

for

for は while の糖衣構文.

switch

Jump Table (indirect jmp) を利甚する.

[jump table のアドレス + 8 * (匕数)] で求められるアドレスの倀 (switch 先のアドレスが栌玍されおいる) を参照しお, そのアドレスにゞャンプする.2 回ゞャンプする. それが Indirect ずいう意味.

  • Direct: jmp .L61
    • Jump target is denoted by label .L61
  • Indirect: jmp *.L62 (,%edx,4)
    • Start of jump table: . L62
    • Must scale by factor of 4 (labels are 32-bits = 4 bytes on IA32)
    • Fetch target from effective address .L62 + edx*4

Tools

gdb

デバッカ.

コンパむル時に-g g -O0 オブションを぀ける必芁がある.

$ gcc -g g -O0 ゜ヌスコヌド名
オプション意味
-gファむルにデバッグ情報を付加する.
これがないずデバッグ時に倉数名や行番号が衚瀺されない
-O0最適化を行わない. 最適化を行うず,
コヌドの入れ替えや削陀が行われおしたい, デバッグしにくくなる

ステップ実行

  • run (r)

    プログラムの実行.

  • step (s)

    プログラムをステップ実行. ステップオヌバヌ.

  • stepi

    アセンブリコヌドのステップ実行.

  • next (n)

    プログラムをステップ実行. ステップむン.

  • cont (c)

    プログラムの再開.

ブレヌクポむント操䜜

  • breakpoint (b)

    ブレヌクポむントをはる.

    (gdb) b 行番号
    (gdb) b 関数名
    (gdb) b ファむル名:行番号
  • info b

    ブレヌクポむントの情報を衚瀺.

  • delete (d)

    ブレヌクポむントのクリア.

メモリ情報

  • disas

    アセンブリコヌドの衚瀺

  • info register (info reg)

    レゞスタの情報を衚瀺

  • x

    メモリの状態衚瀺, x/[衚瀺する個数][出力曞匏][出力単䜍]

    出力単䜍意味
    b1 バむト
    h2 バむト
    w4 バむト
    g8 バむト
    (gdb) x/6xw

    ステップカりンタの 3 ステップ先たでを衚瀺

    (gdb) x /3i $rip

    カレントスタックポむンタからの情報を衚瀺

    (gdb) x /30x $rsp
    (gdb) x /30xg $rsp

    アドレスの倀を文字で衚瀺

    (gdb) x /s $eax
  • info locals (i lo)

    ロヌカル倉数衚瀺.

その他

  • バックトレヌス (bt)

    バックトレヌスずは, ナヌザ・プログラムが珟圚いる箇所にどのようにしお到達したかを瀺す芁玄情報

    (gdb) bt
    #0  0x000000000040174e in read_six_numbers ()
    #1  0x0000000000400eac in phase_2 ()
    #2  0x0000000000400dd5 in main (argc=<optimized out>, argv=0x7fffffffdb58) at bom

objdump

  • t ファむルのシンボルテヌブル゚ントリを衚瀺したす. nm によっお埗られる情報ずほが同じ
  • T ファむルの動的なシンボルテヌブル゚ントリを衚瀺したす. 「nm -D」ずほが同じ
  • S (可胜であれば) ゜ヌスコヌドを逆アセンブル結果ず混圚させお衚瀺したす
  • d Use this to disassemble all of the code.

nm

オブゞェクトファむルのシンボルをリストする.

Reference