「Cとアセンブリ言語で学ぶ計算機プログラミングの基礎概念」読了

25章以降はちょっと読み物風味でアセンブリの話とかあんま出てこないのが残念。それ以前の内容から、なんとなくはイメージできるのでいいけど。

  • 第25章 動的メモリ割当て
  • 第26章 非局所的ジャンプ
  • 第27章 マルチスレッド
  • 第28章 スレッド同期
  • 第29章 例外
  • 第30章 割込み
  • 第31章 非ブロッキング並行データ構造

アセンブリ言語での局所変数

局所変数とはスタック上に確保されたものであり.globlで指定されるものとは異なる。

100までの総和を局所変数を使ってもとめる

int main()
{
  print_int(sum(10));
  print_string("\n");
  return 0;
}

int sum(int n)
{
  int s;
  s = 0;
  while(n>0){
    s = s + n;
    n = n - 1;
  }
  return s;
}

関数後ごとにスタックを設定してsum2で$v0に結果を書き込んで、mainの

move $a0, $v0

で返り値を受ける。

        .data

_s1:    .asciiz "\n"

        .text
        .globl main
main:
        addiu $sp, $sp, -24
    sw    $ra, 20($sp)
    sw    $fp, 16($sp)
    move  $fp, $sp

    li    $a0, 100
    jal   sum
    move  $a0, $v0
    li    $v0, 1
    syscall

    la    $a0, _s1
    li    $v0, 4
    syscall

    li    $v0, 0
    move  $sp, $fp
    lw    $ra, 20($sp)
    lw    $fp, 16($sp)
    addiu $sp, $sp, 24
    jr    $ra

sum:
    addiu $sp, $sp, -12
    sw    $ra, 8($sp)
    sw    $fp, 4($sp)
    move  $fp, $sp

    sw    $zero, 0($fp)

_sum_1:
    slt   $t0, $zero, $a0
    beq   $t0, $zero, _sum_2

    lw    $t1, 0($fp)
    add   $t1, $t1, $a0
    sw    $t1, 0($fp)

    addi  $a0, $a0, -1

    b     _sum_1

_sum_2:
    lw    $v0, 0($fp)
    move  $sp, $fp
    lw    $ra, 8($sp)
    lw    $fp, 4($sp)
    addiu $sp, $sp, 12
    jr    $ra

18章終了

アセンブリ言語での配列

.wordを連続して書くことで、連続したメモリアドレスに語が確保される

# int a[2] = {3, 2, 1};
    .globl    a
a:  .word     3
    .word     2
    .word     1

12章まで読んだ。

spim

グローバル変数の代入

    .data

    .globl src
src: .word 2001

    .globl dst
dst: .word 0

    .text
    .globl main
main:
    la $t0, src
    lw $s0, 0($t0)
    la $t1, dst
    sw $s0, 0($t1)
    li $v0, 0
    jr $ra

実行。printでメモリアドレスとか内容が表示されるので、runの前後で比較する。

$ spim
SPIM Version 7.4 of January 1, 2009
Copyright 1990-2004 by James R. Larus (larus@cs.wisc.edu).
All Rights Reserved.
See the file README for a full copyright notice.
Loaded: /opt/local/share/spim/exceptions.s
(spim) load "ls.as"
(spim) print dst
Data seg @ 0x10010004 (268500996) = 0x00000000 (0)
(spim) print src
Data seg @ 0x10010000 (268500992) = 0x000007d1 (2001)
(spim) run
(spim) print dst
Data seg @ 0x10010004 (268500996) = 0x000007d1 (2001)
(spim) print src
Data seg @ 0x10010000 (268500992) = 0x000007d1 (2001)

MIPS32エミュレータ

SPIM

macだと

sudo port install spim

でOK。

早速のhello world

      .data
msg:  .asciiz "Hello world.\n"

      .text
      .globl main

main:
      li   $v0, 4
      la   $a0,msg
      syscall
      jr   $ra

後半にスレッドとかノンブロッキングの話が出てくるらしいので楽しみ