LoginSignup
14
14

More than 5 years have passed since last update.

Linuxでx86アセンブラ(スタック編)

Posted at

:large_blue_diamond:この記事について

Linuxでx86アセンブラ第6回.アセンブラでのスタックの操作について書いていきます.アセンブラではスタックにより動的にメモリ管理します.このスタックは自動変数の格納先や、関数間の変数の受け渡しに用いられます.また、浮動少数の演算にはスタックの知識は不可欠です.

:large_blue_diamond:スタックとは?

前回の記事で説明したようにdata・bssセクションで定義した領域には先頭のアドレスを保管している変数名でアクセスしました.つまり、アクセスしたいメモリ領域に名前をつけて、その名前を使ってアクセスします.しかし、この方法ではプログラムの実行中に宣言される変数にアクセスすることは難しいです.そこで、名前無しでメモリにアクセスする方法を提供するのがスタックです.
スタックはLIFO構造を持ちます.スタックにデータを追加(プッシュ)すると積み上がっていきます.

Push.png

スタックからデータを取り出す(ポップ)すると積まれたデータの一番上(最後に積まれた)データが取り出されます.
Pop.png

つまり、スタックは名前ではなくスタックにプッシュ・ポップされた順番によってメモリにアクセスできるようにする仕組みです.

:large_blue_diamond:プッシュ

アセンブラでスタックにプッシュするにはpushニーモニック使います.

push <レジスタ・メモリ・フラグ>

スタックの要素にアクセスするにはesp・ebpレジスタを使います.
espはスタックの一番上のアドレスが格納されます.pushが実行されるとスタックにデータが追加されるとともにespが指すアドレスも移動されます.espはpushpopを行うと自動的に指しているアドレスが変わってしまいます.そこで、espの値を一時的に保管する先がebpです.espの値をebpにコピーするにはmovニーモニックを使います.

mov ebp, esp

ポップ

スタックからデータをポップするにはpopニーモニックを使います.

pop <レジスタ・メモリ・フラグ>

ポップされたデータはスタックからなくなります.
ポップする以外にもスタックからデータを取り除く方法があります.
それは、espを動かすことです.

add esp, 8

これによりスタック一番上にあるデータが、スタックからなくなります.

:large_blue_diamond:デモ

スタックの操作方法を説明するサンプルコードです.

stack.asm
section .data

section .bss

section .text

global main

main:
   enter 0,0
   nop

.push:
   mov rax, 1
   push rax
   mov rax, 2
   push rax
   mov rax, 3
   push rax
   mov rax, 4
   push rax

.pop:
   mov rax, [rsp]
   mov rax, [rsp + 8]
   mov rax, [rsp + 16]
   mov rax, [rsp + 24]
   pop rax
   pop rax
   pop rax
   pop rax

.final:
    mov eax, 0
    leave
    ret

コンパイルして、gdb上で実行してみてください.
スタックもメモリの一種です.なのでgdbないでスタックを表示するにはメモリの中身を表示するコマンドxを用います.
このプログラムでは

x/20 $rsp

で、スタックの中身を表示することができます.

参考文献

↓↓:bowtie:過去の投稿もよろしくね:bowtie:↓↓

↓↓:bowtie:コメントをいただけたら励みになります:bowtie:↓↓

14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14