Tommy's Blog

Cとアセンブラ1

Cとアセンブリ言語で学ぶ計算機プログラミングの基礎概念 - プログラムはプロセッサ上でどのように実行されるのか -という本を最近読んでいる。
今回は文字列について見てみる。文字列ムズカシイナンモワカラン。

文字列とローカル変数

以下のコードがどのようにアセンブリ言語で表されるかを見てみる。ここではアセンブリ言語としてMIPSを用いる。

int main(void) {
  char p[] = "HOGEhoge";
}

上記のコードは以下のような感じになる。

     .data
LC0: .ascii "HOGE"
LC1: .ascii "hoge"

     .text
     .globl main
main:
     # スタックフレームの確保
     addiu   $sp,$sp,-32
     sw      $fp,28($sp)
     move    $fp,$sp

     # レジスタにLC0をロード -> スタックフレーム内にストア
     lw $t9, LC0
     sw $t9,20($fp)
     # レジスタにLC1をロード -> スタックフレーム内にストア
     lw $t9, LC1
     sw $t9, 24($fp)

     # 文字列を出力する
     li $v0, 4
     la $a0, 20($fp)
     syscall

     # return 0;
     li $v0, 0
     jr $ra

compiler explorerではこのようになる。やっていることはほとんど同じで、まずデータセグメントに"HOGEhoge"という文字列を配置している。次にスタックフレームを確保し、配置された文字列をローカル変数p(つまりはスタックフレーム内)にコピーしている(ほんまか?)。

ということは、同じ文字列が2つ存在するためメモリ容量としては無駄と言えば無駄。なんでこうなっているのだろう。

ちなみに文字列が短い場合はテキストセグメントに即値として埋め込まれる。

まとめ

  • 文字列をローカル変数として定義した場合、データセグメントからコピーされる。
      - 整数などの場合はli命令とsw命令1回ずつで済むので、長い文字列の場合は遅くなりそう(計測してみる)
  • 文字列ナンモワカラン