質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.11%

以前に質問した「アセンブリプログラムの解説」に関しての質問です。

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,759

carnage0216

score 129

以下の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-(width*3)%4でも問題ないとのことですが、1ピクセルが3バイトでありwidth自体がRGB3バイトを含んでいるのだとしたらwidth*3と書いてしますと、RGBを含んでいるwidthと掛けたRGBが重複してしまう気がするのですが、
個人的には本を読む限り、width=(n個の横のピクセル)*(3バイト/1ピクセル)を表しているように思えます。width/4の4はRGBが3バイト故に4でバイト単位でwidthを割っており、4バイトで高速化を考えているため、widthの余りのとなった1~3バイト数のRGBはダミーデータとして扱われる。
以上のことからアセンブリプログラム内にwidthをどのように扱うか定義されていないところを見ると、
ダミーデータを求める計算式はwidth/4と書くのが正しいものであり、本に書いてある4-(width*3)%4の方はたまたま、3を掛けたらwidth/4と同じダミーデータのバイト数を得られただけだと考えています。
なので、「実は乗算も減算も不要、即ちあの部分は無駄なコードなのです」に関しては、無駄ではなく、間違ったコードなのではないかと考えています。
もしかしたら作者なりに都合よくなるようにするために書いたコードなのかもしれませんが。

皆様はどのように考えるかを解答していただけると大変ありがたいです。
どうかよろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • carnage0216

    2018/03/19 09:26

    わかりわかりにくくてすいません。widthは画像の幅を表しているので、RGBの情報をすでに持っているのではないかとないかと考えているのです

    キャンセル

  • fuzzball

    2018/03/19 10:29

    画像の幅と言われたら640とか1024とか、ただの数値で、どうしてそこに「RGB情報が含まれている」と考えるのか理解できませんし、実際、RGB情報は含まれていません。

    キャンセル

  • carnage0216

    2018/03/19 11:45

    無知でした。ありがとうございます。 「画像」の幅だったため、既にrgbの情報が入っていると思っていました。

    キャンセル

回答 4

+3

前の質問アセンブリプログラムの解説でベストアンサーになっている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/21 01:07

    asmさん 詳しい解説と確認、どうもありがとうございます。

    キャンセル

  • 2018/03/21 02:16

    carnage0216さん
    > それでも同様に+3して&-4でパディング込みの1行ごとのデータサイズが得られます。
    この1行ごとのデータサイズのことをストライドと呼びます。
    そもそもなんでパディングを求めていたかというと、このストライドを求めるためです。

    ストライドをどう求めるかはよくある質問です。
    1bitから32bitまでのBITMAPに対応する計算方法ももうすでに誰かが考えています。
    ですので、興味があればbitmap strideなどで検索してみてください。

    キャンセル

  • 2018/03/21 04:01

    > もともとのプログラムではwidthが4の倍数であるときはjzでジャンプしています。
    これは失礼しました. そこまでは読み込んでいませんでした. ともあれ普段高級言語しか使っていないとこういったネイティブに近い考え方も新鮮でいいですね.

    キャンセル

+2

※質問への直接な回答ではありません。


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/21 01:05

    defghi1977さん。
    mkgreiさん。
    どうもありがとうございます。
    逃げずに頑張ります。

    キャンセル

  • 2018/03/21 04:09 編集

    > 前にAVRを進めていると言っていたのを覚えていらっしゃいますか。
    いいえ, 私はちょっとした興味(なんかいつもコメントが上がっているなあと思った)から質問を覗いてみただけの, ただのJavaScript使いです. 以前JavaScriptでBitmap触った時と似たようなことやったな―とつい口を挟んでしまっただけです.

    > まるで私ですね。
    あなたは違いますよ. あなたの質問にはさほどマイナスは付いていません. そこは誇っていい.

    向上心に欠ける人の質問には-1などではなくもっとたくさんの低評価が付いています. こういう人たちはあなたと違って回答やコメントをはじめから全く読んでいないし聞きもしない. すると回答する側のストレスのみが蓄積していき, 答える気力すら失せるという本当の意味での悪循環を引き起こすため, 低評価を付けることで皆の目から遠ざけているのです.

    キャンセル

  • 2018/03/21 21:50

    そうなのですね。
    私の場合は読むにしても理解に時間がかかり、回答者様にご迷惑をおかけしたりで、もっと理解力と読解力を付けないといけないです。基礎能力もです。

    キャンセル

checkベストアンサー

+1

元質問も長文なのであまり読んでませんが、そもそもそのコードはどこからもってきたもんなんでしょうか。
それがどういう意図があるのかというのはそれこそ作者に聞いてこないと、他人がいくら議論したところで机上の空論にしかならないと思いますが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/19 11:58

    指摘するのはまかせてくれたまえ。

    んで、それに対し不快になるから、とか、私は馬鹿だから、とか甘ったれたことは言わないように。
    そういうのは、逃げにしかならん。

    質問されて、それに回答する、それで結局理解できないってことでもそれは別に構わん。
    しかし、そこでプログラマには向いてない、とか無謀だった、とかで逃げられると、ナンノコッチャってことになるのを理解してくれ

    キャンセル

  • 2018/03/19 12:03

    わかりました。
    まだ、未熟のニュービーですが、どうもよろしくお願い致します。
    y_waiwai様、生意気な事を言ってしまい申し訳ありませんでした。

    キャンセル

  • 2018/03/20 18:31

    だから逃げるんじゃねえ。
    ひとに迷惑かけてるってのはわかりきってることなんだから、これもコミで開き直らんとアカンだろ
    その理解の悪さはオレも病的だと思うが、そうならなおさら食い下がっていかんと人並みにもなれんってことなんだから
    まー、ID変えるってならそんでもいいとは思うがw

    #返答不要

    キャンセル

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 22:53

    どうもありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る