この記事について
Linuxでx86アセンブラ第6回.アセンブラでのスタックの操作について書いていきます.アセンブラではスタックにより動的にメモリ管理します.このスタックは自動変数の格納先や、関数間の変数の受け渡しに用いられます.また、浮動少数の演算にはスタックの知識は不可欠です.
スタックとは?
前回の記事で説明したようにdata・bssセクションで定義した領域には先頭のアドレスを保管している変数名でアクセスしました.つまり、アクセスしたいメモリ領域に名前をつけて、その名前を使ってアクセスします.しかし、この方法ではプログラムの実行中に宣言される変数にアクセスすることは難しいです.そこで、名前無しでメモリにアクセスする方法を提供するのがスタックです.
スタックはLIFO構造を持ちます.スタックにデータを追加(プッシュ)すると積み上がっていきます.
スタックからデータを取り出す(ポップ)すると積まれたデータの一番上(最後に積まれた)データが取り出されます.
つまり、スタックは名前ではなくスタックにプッシュ・ポップされた順番によってメモリにアクセスできるようにする仕組みです.
プッシュ
アセンブラでスタックにプッシュするにはpush
ニーモニック使います.
push <レジスタ・メモリ・フラグ>
スタックの要素にアクセスするにはesp・ebpレジスタを使います.
espはスタックの一番上のアドレスが格納されます.push
が実行されるとスタックにデータが追加されるとともにespが指すアドレスも移動されます.espはpush
・pop
を行うと自動的に指しているアドレスが変わってしまいます.そこで、espの値を一時的に保管する先がebpです.espの値をebpにコピーするにはmov
ニーモニックを使います.
mov ebp, esp
ポップ
スタックからデータをポップするにはpop
ニーモニックを使います.
pop <レジスタ・メモリ・フラグ>
ポップされたデータはスタックからなくなります.
ポップする以外にもスタックからデータを取り除く方法があります.
それは、espを動かすことです.
add esp, 8
これによりスタック一番上にあるデータが、スタックからなくなります.
デモ
スタックの操作方法を説明するサンプルコードです.
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
で、スタックの中身を表示することができます.
参考文献
- NASM development team site:
http://www.nasm.us/ - GDB: The GNU Project Debugger site:
https://www.gnu.org/software/gdb/ - Assembly Language Step-by-Step: Programming with Linux:
http://www.amazon.co.jp/Assembly-Language-Step---Step-Programming/dp/0470497025/ref=sr_1_1?ie=UTF8&qid=1446704607&sr=8-1&keywords=assembly+language+step+by+step - Stack Analysis with GDB:
http://resources.infosecinstitute.com/stack-analysis-with-gdb/ - HUMAN PICTOGRAM 2.0
http://pictogram2.com/
↓↓過去の投稿もよろしくね↓↓
-
Linuxでx86アセンブラ(基本的なコードの構造編)
http://qiita.com/MoriokaReimen/items/b320e6cc82c8873a602f -
Linuxでx86アセンブラ(論理演算編)
http://qiita.com/MoriokaReimen/items/bf863585616ad0a0a969 -
Linuxでx86アセンブラ(四則演算編)
http://qiita.com/MoriokaReimen/items/4853587dcb9eb96fab62 -
Linuxでx86アセンブラ(Cとの連携編)
http://qiita.com/MoriokaReimen/items/590a4ddb3de15bfacb4b -
Linuxでx86アセンブラ(道具編)
http://qiita.com/MoriokaReimen/items/b316a68d76c1eafa18f8 -
tmuxの使い方
http://qiita.com/MoriokaReimen/items/d7d5b158cb412dd65a60
↓↓コメントをいただけたら励みになります↓↓