1: 2007-03-24 (土) 15:29:55 |
現: 2024-01-06 (土) 22:37:41 |
- | [[NASK/書式]] | + | COLOR(red){くっそ!アカン!どうも理解が甘い!以下は間違ってます!(お勉強&再整理開始・・・) } |
| | | |
- | 対象に数値等を代入する場合、桁を指定してやる必要がある。 | + | ---- |
| + | -桁指定の考え方は、''基本は全て指定しよ!''ってことでいいのかな・・・ |
| + | -たとえばレジスタ相手。これだって、「指定して間違い」ってわけじゃないはず。ええと・・・ |
| | | |
- | たとえば0x11を代入しようとした場合、 | + | MOV AX,0x11 ←まあ問題ないよね?相手がAXなんだからイヤでも16ビット |
| + | |
| + | MOV AX, WORD 0x11 ←無駄ではあるが、これは「間違い」だろうか?? |
| | | |
- | -8ビット(0x11)なのか? | + | ・・・ふむ・・・実験の結果、少なくとも「間違いではない」ようだ・・・ |
- | -16ビット(0x0011)なのか? | + | |
- | -32ビット(0x00000011)なのか? | + | |
| | | |
- | を教えてやらないといけない。(それによって挙動が変化するので) | + | こういうのはおかしくなるかな??? |
| | | |
- | |8ビット指定|BYTE| | + | MOV WORD AX,WORD 0x11 |
- | |16ビット指定|WORD| | + | |
- | |32ビット指定|DWORD| | + | |
| | | |
- | -具体例(8ビット指定) | + | あれれれ?? これも正常にコンパイルできたなぁ。これも、「別に間違いではない」って理解でいいのかな?? |
- | MOV [0x0042],0x11 | + | |
- | ↑ | + | たとえばこうしたとするよね? |
- | 間違い。0x11というが、これは0x11(8ビット)なのか、0x0011(16ビット)なのか分らない! | + | MOV [0x00ff],0x11 |
| + | |
| + | これが間違いなのは分る。正解は |
| + | MOV [0x00ff],WORD 0x11 |
| + | これでコンパイルが通る。・・・しかし疑問だ。 |
| + | -最初の、アドレスを指定している部分。ここ、0x00ffって言うけど、これが0xffなのか、0x00ffなのか、0x000000ffなのか・・・って、おい!!! |
| + | |
| + | ''あ〜!'' そっか!なるほどなるほど!。そうだよ!アドレス指定の場合は、[0xff]も[0x00ff]も[0x000000ff]も同じことじゃないか!!! |
| + | |
| + | ん?じゃあもしかして・・・・ |
| + | MOV WORD [0x00ff],WORD 0x11 |
| + | これもいいの??? |
| + | |
| + | あっちゃぁ〜。いいんじゃん!(エラーないし、同じバイナリが出てくる) |
| + | |
| + | うーん。しかしそうなると分らん。P37の、 MOV BYTE [678],123 。これはどう理解すれば・・・ |
| + | |
| + | あーーー!! まってまって??。勘違いしてたかも!? |
| + | |
| + | ''値の桁数はわからない''ってのがおかしいのか。だって、0x11も0x0011も0x00000011も値としてはまったく同じことなんだよね??? |
| + | |
| + | メモリのほうに桁指定を入れるってのはようするに、「メモリ素子何個使う?」っていう理解でいいのかな???? |
| + | |
| + | ・・・そうすると、たとえば |
| + | MOV BYTE [678],0x11223344 |
| + | こんなことしたらどうなるの???? |
| + | |
| + | あー・・・エラーになる。じゃ、これは? |
| + | MOV BYTE [678],0x00000044 |
| + | |
| + | ''おーーーー!!'' エラー出ない!!!!!! |
| + | |
| + | こんな実験もしてみた。 |
| + | MOV AX,0x00000044 ←エラーなし |
| + | |
| + | MOV AX,0x11223344 ←エラー!! |
| + | |
| + | おぉ!予測どおり!しかも、 MOV AX,0x11223344 と MOV BYTE [678],0x11223344 は、同じエラー(data range error.)が出る!! 分ってきたぞ!!! |
| + | |
| + | じゃあこれはどうなる? |
| + | たとえば0x10番地に0x11、0x11番地に0x22を入れておいたとして・・・ |
| + | MOV AX, [0x10] ← これは分る。AXには、0x2211が代入されるはず。 |
| + | MOV AX, BYTE [0x10] ← こうやればAXには0x0011が入るのか? |
| + | おーー! エラー! |
| + | さらにこんなの・・・ |
| + | MOV AL,BYTE 0x11223344 |
| + | うほ!エラーだよ!!!。しかもデータレンジのエラー! |
| + | |
| + | |
| + | ・・・わかってきたぞ・・・。NASK(あるいはアセンブラ?)では、とにもかくにも、''「切捨ては決してしない」''ってことなんじゃないのか??? |
| + | |
| + | |
| + | |
| + | |
| + | **こういう法則かなぁ・・・ [#hfd51b04] |
| + | -アセンブラでは、全ての代入に桁指定をする |
| + | -補完はするが、決して切り捨てをしない |
| + | |
| + | 相手がレジスタだろうがなんだろうが、とにかく全て桁を指定する! |
| + | |
| + | 当たり前だが、桁指定と指定された物が矛盾してはいけない。 |
| + | |
| + | MOV WORD AX,WORD 0x1122 |
| + | |
| + | MOV BYTE [0x0043],BYTE 0x11 |
| + | |
| + | MOV WORD [0x0044],WORD DX |
| + | |
| + | ※どれも問題ない。とにかく全て桁を指定する。 |
| + | |
| + | 問題がある指定 |
| + | 指定と矛盾する |
| + | MOV BYTE AX,BYTE 0x13 ← AXは16bitのレジスタ。BYTE指定はおかしい |
| + | |
| + | 切捨ては決してしてくれない |
| + | MOV BYTE AL,BYTE 0x11223344 ←たとえBYTE指定しても、0x11223344は8bitデータじゃない。 |
| + | (自動で0x11223344を0x44に切り捨てしたりしてくれない) |
| + | |
| + | 以下は問題がない(補完) |
| + | MOV WORD AX, WORD 0x11 ←0x11と0x0011は同じこと。WORD指定で頭00を補完してくれる |
| + | |
| + | MOV WORD AX,WORD 0x00000011 ←一見切り捨てに見えるが、0x00000011と0x11はまったく同じこと。 |
| + | なので、「元々0x11だった」と理解すれば、補完になる |
| + | |
| + | COLOR(blue){以上の単純な法則で全てOK。これで少なくとも''「間違いである!」''ということは起きなくなる} |
| + | |
| + | |
| + | **実際の書き方(省略) [#te73527d] |
| + | 上記の簡単な法則が全て。後は、「省略しても特定できるかどうか」だけとなる。 |
| + | |
| + | 省略しても特定できるのでエラーにならない例 |
| + | MOV WORD AX,WORD 0x1122 ←本来の書き方 |
| + | MOV AX,WORD 0x1122 ←AXは16bitレジスタと解りきっているので省略可 |
| + | MOV AX,0x1122 ←但し注意。これは0x1122が16bitと特定できるのではない。 |
| + | ・AXが16bitなんだから、当然値も16bitだろう |
| + | ・うん、4桁だし、問題もないよね? |
| + | と、こう理解しているに過ぎない。 |
| + | |
| + | MOV WORD DX,WORD 0x11 ←本来の書き方 |
| + | MOV DX,WORD 0x11 ←DXは16bitに特定できる。0x11も0x0011と同じ |
| + | なのでWORD指定しても矛盾しない(補完) |
| + | MOV DX,0x11 ←上の例と同じで、0x11を見て判断しているのではない。 |
| + | あくまでもDX(本来ならWORD DX)によって16bitに |
| + | 特定され、0x11は16bit化しても矛盾しないので |
| + | エラーにならないに過ぎない。 |
| + | |
| + | MOV BYTE [0x0041],BYTE 0x22 ←本来の書き方(エラーにならない) |
| + | MOV BYTE [0x0041],0x22 ←・メモリに対しBYTE指定。当然値もBYTEだろう。 |
| + | ・0x22はBYTE指定と矛盾しないな。OK! |
| + | ・エラーにならない。 |
| + | MOV [0x0041],BYTE 0x22 ←・メモリにバイト指定がないなぁ。何バイトだ? |
| + | ・うん、値にはBYTE指定か。じゃあメモリをBYTEと |
| + | 決め付けても問題ないだろう。 |
| + | ・エラーにならない |
| + | -COLOR(blue){下2例のメモリへのMOV。メモリ側と値側。とにかくどちらか一方でも指定があれば他方は特定できる。・・・じゃ、どっちを省略するのが正しい??} |
| + | -COLOR(blue){少なくともどちらを省略してもエラーにはならない。それどころかどちらを省略しても、また省略しなくても、出てくるバイナリはまったく同一である。} |
| + | MOV BYTE [0x0041],BYTE 0x22 ←┐ |
| + | MOV BYTE [0x0041], 0x22 ←┼── 全て同じこと。バイナリも同一 |
| + | MOV [0x0041],BYTE 0x22 ←┘ |
| + | |
| + | |
| + | |
| + | 特定ができない例:(エラーになる) |
| + | MOV [0x0041],0x11 ←・ん?何バイト?メモリにも値にも指定がないぞ? |
| + | ・え?値が0x11だからBYTE指定だろうって? |
| + | ・それは解らんぞ?もし0x0011なら0x0041番地と0x0042番地 |
| + | にも書かなくちゃいけない。どっちだ? |
| + | ・エラーになる(特定しきれない) |
| + | |
| + | MOV [0x0041],0x1122 ←・これならいいだろう?値は16bit。WORD指定だ! |
| + | ・値が0x001122っていう可能性はないの?それ次第 |
| + | では0x0043にも書かなくちゃいけない。どっち? |
| + | ・エラーになる(特定しきれない) |
| + | |
| + | MOV [0x0041],0x11223344 ←・これならどうだ!お前DWORDまでだろう? |
| + | 値が32bitなんだから、値から32bit(DWORD指定)と |
| + | 特定できるはずだ! |
| + | ・この値がさ、0x000000000011223344じゃないって |
| + | 保障ある?。ないよね?。やっぱり特定できない。 |
| + | ・エラーになる(特定しきれない) |
| + | |
| + | |
| + | -COLOR(blue){省略していいのか悪いのか、ごっちゃになってわからなくなっちゃった!} |
| + | --COLOR(red){そういう場合はなまじっか考えず、''全部指定しちゃう''のがいい。そうすれば少なくともエラーにはならないし、正解の省略と出てくるバイナリは変わらない。それでもエラーになるっていうなら、矛盾・切捨て違反のどちらかだと、間違いの特定もできるし。} |
| + | |
| + | |
| + | |
| + | |
| + | ***実際の挙動(メモリへの代入) [#v35a16ba] |
| + | -8ビット指定 |
| | | |
| MOV BYTE [0x0042],0x11 | | MOV BYTE [0x0042],0x11 |
- | ↑ | + | |
- | 桁が指定された。BYTEなので、0x11は素直に0x11(8ビット)だと解釈される | + | : ├────┤ : ├────┤ |
| + | 0x40番地 │ 0x32 │ 0x40番地 │ 0x32 │ |
| + | ├────┤ ├────┤ |
| + | 0x41番地 │ 0xA1 │ 0x41番地 │ 0xA1 │ |
| + | ├────┤ ├────┤ |
| + | 0x42番地 │ 0x4F │ ⇒ 0x42番地 │ 0x11 │ ←ここだけ変化 |
| + | ├────┤ ├────┤ |
| + | 0x43番地 │ 0x96 │ 0x43番地 │ 0x96 │ |
| + | ├────┤ ├────┤ |
| + | 0x44番地 │ 0xEF │ 0x44番地 │ 0xEF │ |
| + | ├────┤ ├────┤ |
| + | 0x45番地 │ 0x89 │ 0x45番地 │ 0x89 │ |
| + | ├────┤ ├────┤ |
| + | 0x46番地 │ 0xFF │ 0x46番地 │ 0xFF │ |
| + | : ├────┤ : ├────┤ |
| | | |
| | | |
- | -具体例(16ビット指定) | + | -16ビット指定 |
- | MOV [0x0042],0x11 | + | |
- | ↑ | + | |
- | 間違い。0x11というが、これは0x11(8ビット)なのか、0x0011(16ビット)なのか分らない! | + | |
| | | |
| MOV WORD [0x0042],0x11 | | MOV WORD [0x0042],0x11 |
- | ↑ | + | |
- | 桁が指定された。WORDなので、0x11は0x0011(16ビット)だと解釈される | + | : ├────┤ : ├────┤ |
| + | 0x40番地 │ 0x32 │ 0x40番地 │ 0x32 │ |
| + | ├────┤ ├────┤ |
| + | 0x41番地 │ 0xA1 │ 0x41番地 │ 0xA1 │ |
| + | ├────┤ ├────┤ |
| + | 0x42番地 │ 0x4F │ ⇒ 0x42番地 │ 0x11 │ ←値は16ビットの0x0011と |
| + | ├────┤ ├────┤ 解釈される。値が16ビット |
| + | 0x43番地 │ 0x96 │ ⇒ 0x43番地 │ 0x00 │ ←なのだから0x43も変化する |
| + | ├────┤ ├────┤ (リトルエンディアンで値が |
| + | 0x44番地 │ 0xEF │ 0x44番地 │ 0xEF │ 逆さまになるのに注意) |
| + | ├────┤ ├────┤ |
| + | 0x45番地 │ 0x89 │ 0x45番地 │ 0x89 │ |
| + | ├────┤ ├────┤ |
| + | 0x46番地 │ 0xFF │ 0x46番地 │ 0xFF │ |
| + | : ├────┤ : ├────┤ |
| + | |
| + | |
| + | |
| + | |
| + | |
| + | |
| + | -32ビット指定 |
| + | |
| + | MOV DWORD [0x0042],0x11 |
| + | |
| + | : ├────┤ : ├────┤ |
| + | 0x40番地 │ 0x32 │ 0x40番地 │ 0x32 │ |
| + | ├────┤ ├────┤ |
| + | 0x41番地 │ 0xA1 │ 0x41番地 │ 0xA1 │ |
| + | ├────┤ ├────┤ |
| + | 0x42番地 │ 0x4F │ ⇒ 0x42番地 │ 0x11 │ ←値は32ビットの0x00000011と |
| + | ├────┤ ├────┤ 解釈される。値が32ビット |
| + | 0x43番地 │ 0x96 │ ⇒ 0x43番地 │ 0x00 │ ←なのだから0x43、0x44、0x45 |
| + | ├────┤ ├────┤ まで変化する |
| + | 0x44番地 │ 0xEF │ ⇒ 0x44番地 │ 0x00 │ ←(リトルエンディアンで値が |
| + | ├────┤ ├────┤ 逆さまになるのに注意) |
| + | 0x45番地 │ 0x89 │ ⇒ 0x45番地 │ 0x00 │ ← |
| + | ├────┤ ├────┤ |
| + | 0x46番地 │ 0xFF │ 0x46番地 │ 0xFF │ |
| + | : ├────┤ : ├────┤ |