LoginSignup
0

More than 5 years have passed since last update.

nasmで1~100まで数える

Last updated at Posted at 2017-10-13

はじめに

nasmで1~100を表示させるコードを書いたので、ここにメモしました。
基本的には前回の応用です。読んでください。

コード

ソースコード

; 初期設定
extern  printf                  ; printf関数を持ってくる

; データセクション
section .data
    fmt: db "%d", 10, 0         ; printfで用いるフォーマット

; コードセクション
section .text
    global _start               ; _startを指名

; スタート
_start:
    ; 1. 必要な値の代入
    mov     rdx, 1              ; カウントの初期化

    mov     rcx, 100            ; ループ回数

; 2. ループの先頭
_loop:
    ; 3. 維持して置きたい値の避難
    push   rcx                  ; rcxの避難
    push   rdx                  ; rdxの避難

    ; printfに用いる値のセット
    mov    rdi, fmt             ; フォーマット
    mov    rsi, rdx             ; カウントしている値

    ; コール
    call   printf               ; printfをコール

    ; 4. スタックの値をレジスタに戻す
    pop    rdx                  ; rdxを持ってくる
    pop    rcx                  ; rcxを持ってくる

    ; 5. インクリメントする
    add    rdx, 1               ; rdxに1加算

    ; 6. ループバック
    loop _loop                  ; ループバック

; 後処理
fin:
    mov    rax, 1               ; システムコール番号(sys_exit)
    mov    rbx, 0               ; 終了ステータスコード
    int    0x80                 ; システムコール

実行

$ nasm -f elf64 ファイル名
$ gcc 生成したオブジェクトファイル名 -nostartfiles -no-pie
$ ./a.out
1
2
3
4
.
.
.
97
98
99
100

解説

1. 各値の指定 

表示するようの値としてrdxを用いるので、初期値として1を代入します
x86-64だとrcxに置いた回数だけループされるので、以下のコードでrcxに100を入れます。

mov     rdx, 1 
mov     rcx, 100

2. 6. ループをセット

_loopというラベルを貼り、loop _loopが来たときrcxがゼロ以外ならループします。

_loop:
ここにコード
loop _loop

3. 維持して置きたい値の避難

printfのコール時にレジスタの値が消えてしまうので、スタックに避難させます。

push    rcx
push    rdx

4. 避難させたスタックをレジスタに戻す

上記のスタックに避難させた各値をレジスタに戻します。

pop    rcx
pop    rdx

5. rdxに1加算

rdxに1加算します。

add    rdx, 1 

さいごに

こんな感じで、1~100を呼び出しました。
何か間違ったこと等あればコメントください。

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
0