質問: アセンブリ言語のプルグラムに関する質問です。 ある本でアセンブリを勉強をしているのですがわからない部分があります。 横幅が4の倍数協会にない場合のダミーデータを計算するようなのですが、 なぜダミーデータを計算するのかわかりません。 横幅が4倍でない場合にレジスタと演算回路で計算して4で割り切れない場合の余りを捨てるという意味でしょうか?というかアセンブリプログラムはそのように書いてあるのでしょうか? 個人的に4倍ではなく1バイトが8bitなので8で割ったほうが都合がよいように思えますが。 計算部分とアセンブリ言語のプログラムのある部分に疑問があります。 以上について質問します。疑問のある部分に丸で囲んだ数字を置きます。 wMargineをゼロクリアにして、widthをeaxレジスタに代入します。 4で割った余りを算出するためにeaxレジスタを3で論理積を行う。 (⓵ここで3倍した理由は4で割った際の余りが3以上になるようにするためですか? だとしたらもともとダミーデータが出ないように計算したほうがいいように思えますが。) 最下位2bitのいずれかが立っているかを検査します。 もし、4で割ったときに余りがあったら、widthを3倍し、それを4で割って得る。そして4から余りを引いてwMargineに設定する。 (⓶「そして4から余りを引いてwMargineに設定する。」の部分の4から余りを引く理由がわかりません) プログラム通りeaxレジスタにwidthを入れます。そしてebxレジスタに3を代入し乗算します。 (⓷eaxレジスタとebxレジスタを乗算するのはわかるのですがプログラムにはmul ebxとしか書いていないのですが、なぜmul ebxと書いただけでeaxレジスタとebxレジスタを乗算する結果がebxに入る理由がわかりません。演算結果を一旦別のレジスタに入れた後に、mov命令でebxに演算結果をいれるならば理解できます。このアセンブリプログラムを出力したCPUの構造故にmul ebxと書いただけでeaxレジスタとebxレジスタの乗算結果がebxに入るのでしょうか?だとしたら仕方ないです。) その後4バイトの乗算であるため上位4バイトがedxと下位4バイトがeaxレジスタへ代入されるようです (⓸この乗算結果を二つのレジスタに乗算の結果を分割して入れている命令部分はプログラムのどこに書いてあるのでしょうか? どのようにアセンブリ命令を書くことで分割してレジスタに入れられたのでしょうか?) 最後にダミーデータを知るために下位4バイトを入れたeaxレジスタと0x00000003で乗算して余りを取得したと書いてあります。これでダミーデータが得られたそうですが、なぜ得られたのか解説をよんでもいまいちわかりません。(⓹下位4バイトを入れたeaxレジスタと0x00000003で乗算して余りを取得したと書いてあります。これでダミーデータが得られた理由がわかりません。また何で割ったのかわからないのですがアセンブリプログラムには書いてあるでしょうか?) プログラムは以下の通りです。 ``` mov wMargine, 0 mov eax, width /* 幅 */ and eax, 0x00000003 /* %4 */ jz no_margin xor edx, edx /* クリア */ mov eax, width /* 幅 */ mov ebx, 3 /* 3 */ mul ebx /* 幅x 3 */ and eax, 0x00000003 /* %4 */ mov ebx, 4 /* 4 */ sub ebx, eax mov wMargine, ebx ``` 以上5つの質問でありますが、どうか解説して頂けると大変助かります。 C言語を勉強している上でより技術を磨くためにアセンブリ言語を身に着けたいと思います。 どうかよろしくお願いいたします。 修正 論理積と足し算を勘違いして使っていました。 ようやく回答者様の皆様の回答が理解できてきました。 以後できる限り気を付けて質問します。 どうかよろしくお願いいたします。 本当に申し訳ありませんでした。 3/19 復習している際に疑問が出来たので再度以下の事に関して質問したいのですが、ここでは書きにくいため新しく質問を作ります。回答していただけると大変ありがたいです。 一時的に質問をしないとのことでしたが今回に関してはどうかお許しください。
回答: おそらくビットマップの仕様 > > 水平方向のバイト数が4の倍数ではないときは、0x00で埋めて4の倍数にする。 > > > です。(なんか他にもavi/jpg/png/gif/mpegの仕様で幅に制限あるフォーマットがあった気がするけど思い出せない) > > 個人的に4倍ではなく1バイトが8bitなので8で割ったほうが都合がよいように思えますが。 > > > 1bitには0か1の情報しか詰められませんけど、モノクロ画像でしょうか? #### > ⓵ここで3倍した理由は4で割った際の余りが3以上になるようにするためですか? 24bit bmpなのでは? #### > ⓶「そして4から余りを引いてwMargineに設定する。」の部分の4から余りを引く理由がわかりません 目的は`width * 3 + wMargine== 4の倍数`にしたいのです。 ~~wMargineが1~4とした場合~~ ``` n = width * 3 / 4 width * 3 + wMargine= 4 * (n + 1) ``` ~~この連立方程式を解いてください~~ **編集**:計算するとおかしかったので追記 数の性質です。 ある数`n`の4で割った余りが * 1の時、n+3は4で割り切れる * 2の時、n+2は4で割り切れる * 3の時、n+1は4で割り切れる * 0の時、nは4で割り切れる #### > ⓷eaxレジスタとebxレジスタを乗算するのはわかるのですがプログラムにはmul ebxとしか書いていない #### > ⓸この乗算結果を二つのレジスタに乗算の結果を分割して入れている命令部分はプログラムのどこに書いてあるのでしょうか? 以前の回答でx86_64の仕様書を貼り付けましたので割愛 不明な命令くらい自分で調べましょう。