EmptyRoom

Diary

twitterもはじめました

[384]2008/12/2(Tue) [tag: プログラミング ]
IA-32のlibc.so.6のprintfはfloatの表示を実装してない?

研究で独自アーキテクチャ用のアセンブリ言語・アセンブラを作ってそのテスト中に気づいた…。

まず,普通にCでfloatの値を表示するプログラムを書いてみる。 とりあえず,このファイルをfloat.cとしておく。

#include <stdio.h>

int main(int argc, char *argv[])
{
    float val = 3.14159;
    printf("Value: %f\n", val);

    return 0;
}

そしてこれをコンパイルして実行すると

Value: 3.141590

と出る。これは期待した動作をしている。 さて,ここでgcc -S float.cとしてアセンブリで出力してみると

    .file "float.c"
    .section .rodata
.LC1:
    .string "Value: %f\n"
    .text
.globl main
    .type main, @function
main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl    -4(%ecx)
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %ecx
    subl    $36, %esp
    movl    $0x40490fd0, %eax  #注: この16進数即値はfloatの3.14159
    movl    %eax, -8(%ebp)
    flds    -8(%ebp)
    fstpl   4(%esp)

    movl    $.LC1, (%esp)
    call    printf
    movl    $0, %eax
    addl    $36, %esp
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.3.2-1ubuntu11) 4.3.2"
    .section    .note.GNU-stack,"",@progbits

注目して欲しいのは太字の部分。 下に抜き出したものと,それぞれの命令の動作について書いてみる。

movl    $0x40490fd0, %eax  # 3.14159 を%eaxレジスタに移動
movl    %eax, -8(%ebp)     # 3.14159 を%ebp-8の指すメモリに移動
flds    -8(%ebp)           # 浮動小数点レジスタに%ebp-8の指すメモリから移動
fstpl    4(%esp)           # 浮動小数点レジスタの内容を %esp+4の指すメモリに移動(スタックに積む)

なぜいちいち浮動小数点レジスタを介すのか? 欲しい値はすでに一つ目の命令で%eaxに入っているはずで, それをそのままスタックに積めば目的の動作を実現することができるはず。 なので,浮動小数点レジスタを介さずにプログラムを書き直してみると

movl    $0x40490fd0, %eax  # 3.14159 を%eaxレジスタに移動
movl    %eax, 4(%esp)     # 3.14159 をスタックに積む

このように書ける。 ここでこのプログラムをgcc float.sでコンパイルして実行してみると

Value: -0.103642

こんなワケのわからん値が出てくる。しかもこの値,実行するたびに変わりる。 ちなみに,

movl    $0, %eax
movl    %eax, -8(%esp)

のようなコードを挟んでやると,プログラムの出力は常にValue: 0.00000になる。

なぜこのような現象が起こるのか?

実は"Value %f"は32bitの浮動小数点(float)を表示するのではなく, 64bitの浮動小数点(double)を表示するものとして実装されているっぽい(少なくともIA-32では)。 なので一度浮動小数点レジスタを介してfloatからdoubleに変換していたというワケ。 じゃあfloatをそのまま表示することはできないのか?はたぶんYes。

なぜこんな実装になっているのかはよくわからないんだけども, IA-32で浮動小数点を扱う場合,(MMXやSSEを使わなければ)必ずx87由来の80bitの精度を持った浮動小数点レジスタを使うことになる。 float同士の演算であっても,メモリへの結果の格納を除いてすべて80bitの精度で計算されるし,

float val2 = val * 2.71;

とやったとき,GCCはデフォルトで2.71はdouble型として定義する。 ここらへんの開発者はIA-32ではfloatを使うよりdoubleを使う方が自然だと判断している? もしかすると,x87は4バイトのデータを扱うのが苦手なのか? 決定的な理由はよくわからないけど,そうなっているのである…うーん

ということで,よくC言語入門テキストに書いてある

floatの値をpritfで使うには%f,doubleは%lfを使いましょう。

なんて文言は嘘なので信じないように! 俺はこの文言を信じて自分の作っている仮想CPUにバグがあるんじゃないかと数時間疑い,その時間を無駄にしたのだから! (少なくともIA-32, libc.so.6では)

# こっそり追記
# floatに %f, doubleに %lf を使うというのは,
# 他のアーキテクチャへの移植という観点から正しいかもしれない
# ただ,今回のような例外もあることを書いておかないと
# アセンブリから直接libcを叩くときに変な罠にハマってしまう
# そういうところは注意が必要

[383]2008/11/30(Sun) [tag: 日記, アニメ ]
生活健全化計画

気を抜くと生活リズムが普通の人と12時間ずれていたりするので,これはなんとかせねば!と思って, 頑張って生活リズム矯正してます。 で,その計画の一環として外出しました! (これじゃ俺が普段全く外出してないみたいじゃないか!…まぁだいたいそうなんだけど)

そんなこんなでHardOffに行きました。 くだらないものにやたら高い値段が付いていたりでおもしろいです。 今時誰がPen4 1.6GHzを5000円も出して買うんでしょうか。 しかし,予期せぬものがありましたよ。Fender Rhodes! まさかこんなどうしようもない店にあるとは全く思ってなかった。 でも,上下1オクターブ分くらい音が鳴らないのに21万円はどうなのよって思った…。 結局,HardOffでは何も買わずに出た。

まぁそんな感じでHardOffを出たんですが,せっかく外出したんだから(この考えがすでに終わってる気がする) もっと遠出したほうが良いんじゃないかと思って,普段行ったことがない方面に自転車を走らせてみた。 野川沿いをずっと上流に行って,野川公園・武蔵野公園とか。 しかし,東京の川沿いってやたら公園やらそんな憩いの場所があっていいですね。 田舎ではありえない。 あと,周りは金持ちの家ばっかりですね!!orz

JazzLive

月例の。 土曜日にLiveが行われるのは初めてだったんだけど,さすがに人が多いなぁと思った。 その所為かわからないけど,比較的メジャーな曲が多かったんじゃないかなぁと思った。 クラリネットえろい。

日曜朝アニメ

生活リズム健全化計画があるので,朝のアニメはばっちり見ます! …とか言いながら起きたのは10時過ぎなんだよなぁorz

で,テレビを付けてみたらライブオン カードライバー翔 なんてアニメをやってたんですよ。
「カードゲーム系のアニメってよくわからんのよねぇ」
と思って眺めていたんだけど,

なんだこの妹は!

やばい,かわいいぞこれ…とかニヤニヤしながら見てた。 カードバトルシーンの

「お兄ちゃんを攻撃!」

の台詞が非常になんというか,アレな感じで,いやマジで。 ああ,やっぱり土日朝のアニメって侮れないよ! 早起きは三文の得。

実況ログ(mht)
# 実況では「お兄ちゃんのモンスター,おっきいし強そう…」という台詞が人気でした。
[382]2008/11/20(Thu) [tag: 日記 ]
組み込み系システムのイベント

注意) 現在,酒が相当入ってます。

タイトル通り,研究室の用事で組み込み系システムのイベントに行かされてました。

まぁほとんどはうちの大学のOBとかが来て,「今の大学の状況はどうよ?」とか 「○○先生のところで勉強したんだけど,まだいるの?」みたいな話ばかりだったんだけど, イベント3日間あるうちの今日だけはラスト1時間で各ブースが酒とかおつまみを出すようなパーティ(?)が開かれて, ちょうど解禁日であるボジョレ・ヌーボーとかいただくことができました。 わりと高級なものと思われるチーズ・サラミなどもね。

はじめの方はShy Boyな俺は「なんかはずかしい…」とか思ってそこら辺の食べ物に手をつけることができなかったんだけど, 一緒に行ったロシア人が超アグレッシブなおかげで,酒もまわり,そこらへんもしっかり堪能することができるようになりました。 サラミうめーサラミ。

そのロシア人が,特定のブース(小さいところ。 プロ向けのグラフィックチップを作っているところ)をお気に召してしまったようで, 閉場の18:30までずっと入り浸ってしまったりと,色々迷惑をかけてしまったかもしれない。 でも,サラミとチーズがとてもおいしかったです。日本製のワインも。

そんなこんなで,日々の鬱を忘れることができました。 俺に足りないのは実はアルコールだったのかもしれない。

あと,過去に鬱病を患ったことがある友人と同じ職場にいる, 同じく過去に鬱病を患った人に俺は鬱病判定されたので,俺を大事にしてやってください。

#実はロシア人じゃなくて,リトアニア人。
#今日,初めて彼が30歳であることを知った。
#あと,帰りの電車で,健全な精神を持つには体力が必要とか,
#友人は大事だとか,そんな話をずっとしてた。
#アルコールも大事。

#就職先の企業(グループ)も来てたから,
#そこでアピールでもすればいいのにね,俺。
[381]2008/11/13(Thu) [tag: 音楽 ]
らぶらぶもーどでーす

アニメ月詠のOPの「ねこみみもーどでーす」の原曲。 なんでこんなのを今更発掘したかというと, 近々TSUTAYAに行ってCDを借りようと思って,そのためにYoutube徘徊してたから。 最近,新しい音楽とか発掘してないから刺激が足りなかったんだよ!

で,なんでDimitri From Parisかというと,いつか聴こうとずっと思ってたから。 自分が買ったCDのボーナストラックとか,RemixCDなんかに入っていたりで,いくつかDimitriのRemixは持ってたけど,この人自身のアルバムとかは持ってなかったし, どんなのがあるかなぁと思ってYoutubeで探してたところ,この曲にブチ当たったと。 とりあえずDimitriのアルバムをいくつか借りてみよう。…置いてあるかな。

あとはReel PeopleのRemixをやってたRasmus Faberとか,日本のだとKyoto Jazz MassiveとかJazztronikとかを探してこよう…。 最近Club/House系ばっか聴いてるなぁ俺…。踊れもしないのに。

#リンク先はYoutube
[380]2008/11/4(Tue) [tag: ゲーム ]
Garden 鈴村あざみ クリア

昨日の夜からやり始めて,今日の朝7:30ごろにクリア! ああ,ちびっこ委員長かわいいよちびっこ委員長!うおーーー!! 声もなんだか金朋+齋藤彩夏(ホスト部のハニー先輩) ÷ 2 って感じで非常にGood!

しかし,なんだよあのシナリオは! ここまで「俺たちの戦いはこれからだ!」的な終わり方はねーよ!!! しかも,なぜタイトルがGardenなのかも全然わからないし。 主人公がさんざ引っ張ってきた過去の秘密もあっさり話して終わってしまうし! …ああ,そうか,アレだな,水月で言うところのメガネの立ち位置なんだな! ここまで(俺的に)おいしいキャラを出しておいてあのシナリオはねえよぉぉぉ!!!うおおおおお…orz

しかし,エロシーンはちんちん勃たないね! なんというかだね,☆画野朗の絵ってのはえちぃ気分よりも, 娘を微笑ましい目で見ているような気分になる感じだよね! あーちゅっちゅしてえよおおぉぉ…

あと,一枚絵が少なすぎるよこれ…。エロシーンはまぁ並(?)にはあるとしても, 日常シーンの一枚絵が圧倒的に少ない。 あの長さがあってエロ以外の一枚絵が3枚しかないというのは何というか…。 そりゃ色々大変なんだろうけど,絵もシナリオも…。 もっと普通の一枚絵が欲しかったよ…。


ちびっこ委員長(クリックで原寸)
1ページに表示する件数