以下のURL先のプログラムはカラー画像をモノクロに画像に変換するためのプログラムです。
質問したいことは以下のアセンブリプログラムのダミーデータであるwMargineを求める計算部分のアセンブリプログラムに関してです。
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
以前の質問の回答https://teratail.com/questions/115874
ではダミーデータを求める計算式は4-(width3)%4でも問題ないとのことですが、1ピクセルが3バイトでありwidth自体がRGB3バイトを含んでいるのだとしたらwidth3と書いてしますと、RGBを含んでいるwidthと掛けたRGBが重複してしまう気がするのですが、
個人的には本を読む限り、width=(n個の横のピクセル)(3バイト/1ピクセル)を表しているように思えます。width/4の4はRGBが3バイト故に4でバイト単位でwidthを割っており、4バイトで高速化を考えているため、widthの余りのとなった1~3バイト数のRGBはダミーデータとして扱われる。
以上のことからアセンブリプログラム内にwidthをどのように扱うか定義されていないところを見ると、
ダミーデータを求める計算式はwidth/4と書くのが正しいものであり、本に書いてある4-(width3)%4の方はたまたま、3を掛けたらwidth/4と同じダミーデータのバイト数を得られただけだと考えています。
なので、「実は乗算も減算も不要、即ちあの部分は無駄なコードなのです」に関しては、無駄ではなく、間違ったコードなのではないかと考えています。
もしかしたら作者なりに都合よくなるようにするために書いたコードなのかもしれませんが。
皆様はどのように考えるかを解答していただけると大変ありがたいです。
どうかよろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/19 00:26
2018/03/19 00:26
2018/03/19 01:29
2018/03/19 02:45
回答4件
0
前の質問アセンブリプログラムの解説でベストアンサーになっているasmさんの回答が大いに参考になるのですが。
アセンブリ言語の方のプログラムはこの際置いておいて、4 - (width * 3) % 4
の式にあてはめてみてください。
例として画面上の幅(width)は15 としてみましょう。15は幅として小さ過ぎですが気にしないでください。
この場合、RGBデータは (width * 3) で15 * 3 = 45。RGBデータとして全45バイトになるのはいいですよね。次に、4 - (45 % 4) でまず、(45 % 4)の答え、45 / 4 の余り=1。この余りと言うのは4バイト境界からはみ出る分です。はみ出た1バイト分を4バイト境界に収める為にはその差を求めるわけですから、4 - 1 で3。お尻に3バイトを詰める(パディング)します。
ダミーデータを求める計算式はwidth/4と書くのが正しいものであり、
15 / 4 = 3 で商は3で、上の答えと同じになるので一見正しく思えるかもしれませんが、
では、width が200だった場合、200 / 4 = 50 となりますがこれは正しいのでしょうか。
width/4の4はRGBが3バイト故に4でバイト単位でwidthを割っており、4バイトで高速化を考えているため、widthの余りのとなった1~3バイト数のRGBはダミーデータとして扱われる。
言葉の使い方なのか、記述が足りないのか、誤解があるのか判断しかねているのですが、恐らく違います。
**「widthの余りのとなった1~3バイト数のRGBはダミーデータとして扱われる」**のではなく、width * 3で得られた数分のバイト列はビットマップデータとして全て使うはずで、お尻が4バイト境界に収まらない場合、1~3バイトの使われないダミーデータで詰めます。この手の処理はビットマップに限らず、良く行われます。
ですので、「作者が都合のいいように4-をしたり、3を掛けた」訳では無いということが言えます。
また、他の回答者様も書かれていますが、例えばWindowsのビットマップでも各種の形式があります。
carnage0216さんの読まれている書籍でどのようなビットマップを想定しているのかで取り扱いが変わってきますので注意してください。
2018/03/19 追記
解決済みの質問ですが、コメントをいただきましたので追記して補足します。
コメントより
width%4の「何」値と4-(width*3)%4のwidthの「何」の値が1,2,3…と一致しているのかわからないのです。
width = 15
のケースですが、24ビットRGBデータが15画素(ピクセル)分メモリ上に展開すると、以下の図のようになります。
尚、Windowsのビットマップ形式ではRGBはB,G,Rと並ぶので、図でもそのように表記しています。
図を見ていくと分かっていただけると思うのですが、画面に描画する幅、つまり画素数であるwidthの数と、それを表す為のRGBデータのバイト列でのバイト数を分けて考える必要があります。
4バイト境界と3バイトのRGB(B,G,R)データが何度もまたがります。で、この例では1から始めて45バイト目でRGBデータが終わってしまい、45は4で割り切れず、もうひとつ上の4の倍数48を満たせるよう、ダミーで3バイト詰める、と言う訳です。(図の'D'のデータ)
投稿2018/03/19 00:52
編集2018/03/19 02:52総合スコア9183
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/19 00:58
2018/03/19 01:00
2018/03/19 01:05
2018/03/19 01:31
2018/03/19 01:31
2018/03/19 01:38
2018/03/19 01:39
2018/03/19 01:43
2018/03/19 03:09
2018/03/19 03:13
2018/03/19 03:15
2018/03/19 04:59
2018/03/19 05:15
2018/03/19 05:17
2018/03/19 05:19
2018/03/19 05:24
2018/03/19 05:25
2018/03/19 05:29
2018/03/19 05:29
2018/03/19 05:31
2018/03/19 05:35
2018/03/19 05:40
2018/03/19 05:56
2018/03/19 06:23
2018/03/19 06:37
2018/03/19 06:48
2018/03/19 07:23
2018/03/19 07:29
2018/03/19 11:11
2018/03/19 11:47
2018/03/19 11:56
2018/03/19 11:58
2018/03/19 12:18
2018/03/19 12:19
2018/03/19 13:42
2018/03/19 22:56
2018/03/19 23:13
2018/03/19 23:29
2018/03/19 23:30
2018/03/19 23:36
2018/03/19 23:39
2018/03/19 23:45 編集
2018/03/19 23:46
2018/03/19 23:47
2018/03/19 23:48
2018/03/20 00:10
2018/03/20 00:12
2018/03/20 00:35
2018/03/20 00:42
2018/03/20 00:51
2018/03/20 01:13 編集
2018/03/20 01:20
2018/03/20 01:22
2018/03/20 01:25
2018/03/20 01:29
2018/03/20 01:31 編集
2018/03/20 01:35 編集
2018/03/20 01:34
2018/03/20 01:38
2018/03/20 01:42 編集
2018/03/20 01:51
2018/03/20 01:59
2018/03/20 02:05 編集
2018/03/20 02:11 編集
2018/03/20 02:20
2018/03/20 02:25
2018/03/20 02:32 編集
2018/03/20 02:50
2018/03/20 02:55
2018/03/20 03:06
2018/03/20 03:08
2018/03/20 03:09
2018/03/20 03:33
2018/03/20 04:08
2018/03/20 04:13
2018/03/20 04:15
2018/03/20 04:16
2018/03/20 04:29
2018/03/20 05:26 編集
2018/03/20 05:34
2018/03/20 05:39
2018/03/20 05:50
2018/03/20 05:50
2018/03/20 06:32
2018/03/20 06:35
2018/03/20 06:36
2018/03/20 08:54
2018/03/20 08:58
2018/03/20 09:04 編集
2018/03/20 09:18
2018/03/20 10:31
2018/03/20 10:53
2018/03/20 10:59
2018/03/20 11:17
2018/03/20 13:59
2018/03/20 14:07
2018/03/20 14:34
2018/03/20 14:59
2018/03/20 15:46
2018/03/20 15:51
2018/03/20 16:04
2018/03/20 16:07
2018/03/20 16:07
2018/03/20 17:16
2018/03/20 19:01
0
※質問への直接な回答ではありません。
dodox86さんの回答のコメント欄を拝見しました。
carnage0216さん
カオスですね…
サクッと回答が得られていない、というより、
回答をすんなり理解できるほどの基礎がないので、
コメントが発散しています。
そして発散することによって混乱が生じています。
途中から読むのではなく、話をまとめてみてください。
そしてまとめた後にわからない行間を意識してみてください。
どこかに得られた結論をまとめてみないと理解した気になっているだけのように思います。
「つまり〜」、「〜なのですね」などが結構正しくないです。
もっと基礎的なことから勉強しても恥ずかしいことではありません。
https://www.amazon.co.jp/コンピューター-テクノロジー解体新書-ロン・ホワイト/dp/4797384298
はっきり申し上げて、低レイヤーは難しいです。
Pythonのエキスパートでも、C++は相当難しく、C++が達者でもアセンブリは難しいです。
人間がやりたいこととその言語ですぐにできることがかけ離れているからです。
アセンブリ言語で追求するのは前の質問でrubato6809さんがお答えしたような命令文をいかに少なくして少しでも高速化することです。
つまりやりたいことがわかった上で、それをいかに効率よく行うかが議論の対象になります。
ですので、そもそもやりたいことを理解するのに苦労していると話が合わないのです。
Cのコンパイラだってアセンブリ言語で書かれているわけではありません。
https://note.mu/ruiu/n/n44e161a0c243
https://qiita.com/ruiu/items/4d471216b71ab48d8b74
歴史的には低級言語で書かれた部分もありますが、
そこから作ったコンパイラを使ってCでコードを書いてコンパイラを作っていくのです。
どうしてもというのであってもOpenCVなどはいけません。
中身が(多すぎて一人の人間がアセンブリ言語で眺めて理解するには)難しすぎます。
どうしてもというのであれば、ここまで回帰してください。
https://qiita.com/advent-calendar/2017/lowlayer
基礎的でありながら、おもしろいです。
投稿2018/03/20 07:26
編集2018/03/20 07:28総合スコア8560
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/20 08:53
2018/03/20 09:06
2018/03/20 09:22
2018/03/20 10:00
2018/03/20 16:00
2018/03/20 16:03
2018/03/20 16:05
2018/03/20 20:02 編集
2018/03/21 12:50
0
ベストアンサー
元質問も長文なのであまり読んでませんが、そもそもそのコードはどこからもってきたもんなんでしょうか。
それがどういう意図があるのかというのはそれこそ作者に聞いてこないと、他人がいくら議論したところで机上の空論にしかならないと思いますが。
投稿2018/03/18 23:31
総合スコア87749
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/18 23:43
2018/03/18 23:55
2018/03/19 00:04
2018/03/19 00:05
2018/03/19 00:10
2018/03/19 00:42
2018/03/19 00:43
2018/03/19 00:59
2018/03/19 01:44
2018/03/19 01:46
2018/03/19 01:50
2018/03/19 02:11
2018/03/19 02:13
2018/03/19 02:14
2018/03/19 02:16
2018/03/19 02:17
2018/03/19 02:24 編集
2018/03/19 02:47
2018/03/19 02:50
2018/03/19 02:58
2018/03/19 03:03
2018/03/20 09:31
0
コメントは伸びすぎなのでこちらに書きます。
4-(width*3)%4がwidth%4と等しい(ただしwidth≠4n)
これを証明するには高校数学程度の知識と剰余算の分配法則の知識が必要です。
もうこの問題は数学の話なのでwidthはxと置き換えます。
つまり
4-(x*3)%4=x%4 (ただしx≠4n)
を証明する。
1.x=4n+1 の場合
左辺
4-(x*3)%4
=4-((4n+1)*3)%4
=4-(12n+3)%4
=4-(12n%4+3%4)%4 //剰余の分配法則
=4-(0+3)%4
=4-3%4
=4-3
=1
右辺
x%4
=(4n+1)%4
=(4n%4+1%4)%4
=(0+1)%4
=1%4
=1
よって左辺=右辺が成り立つ。
あとは
x=4n+2
x=4n+3
についても同じように計算すれば証明終了
投稿2018/03/20 11:57
総合スコア818
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。