変数値でCxレジスタを初期化できますか? NOの場合、どのように動的にユーザ入力値とCxとを初期化する場合ステートメントワークを完璧にするには?
MOV Cx, varaible
下に示す など?助けてください!
変数値でCxレジスタを初期化できますか? NOの場合、どのように動的にユーザ入力値とCxとを初期化する場合ステートメントワークを完璧にするには?
MOV Cx, varaible
下に示す など?助けてください!
名前についてではなく、精神的なイメージについてです。アセンブリには変数はありません。
マシンには、レジスタ、メモリ、アドレス、および命令付きメモリへのアクセスだけがあります。 変数は、プログラマの論理的な構成要素であり、プログラマは、そのような方法でコードを書くことに決めました。つまり、メモリを「可変」として使用します。しかし、彼がそうしないと決めた場合、または間違いを犯すと、それは変数として動作しません。マシンは気にしません。あなたのコードでたとえば
、あなたは.data
セクションの「変数」のためのメモリを割り当てる:
.Data
var DB ?
これが効果的にメモリに対応している、シンボルvar
に変換します。また、.data
セクションの1バイトを予約します。したがって、次にそこに着陸するように定義されたものは、その後に割り当てられます。次の行に追加する場合はvar2 DB 13
、var2
のアドレスはvar + 1
になります。また、このように、同じアドレスで複数のシンボルを作成することができます
.Data
var:
var2:
DB ?
を両方var
とvar2
シンボルが同じメモリアドレスを指すように定義しています。
それはまだあなたの「変数」精神的な画像のように見えるかもしれませんが、これに対応しているので、私は「ちょうどメモリ」と「変数」の間に別の違いを紹介します:
MOV [var], AL ; store value in AL into memory at address "var"
; your MOV var, AL without brackets works only in MASM/TASM assemblers
; but it is not valid Intel syntax, I will use brackets for every memory access
これは8ビットの値を書き込み、アドレスvar
のメモリへのAL
。ここまでは順調ですね。今質問してください:
MOV CX, [var]
これはコンパイルして実行しますが、期待どおりに動作しません。あなたはメモリに8ビットしか書いておらず、var
のために1バイトしか予約していないからです。しかし、CX
は16ビットレジスタです(上位8ビットはCH
、下位8ビットはCL
です)、この命令はアドレスvar
のメモリから2バイトを読み込みます。 x86はリトルエンディアンであるため、CPUが16ビット値で動作する場合、ローの8ビットを第1バイト(オフセット+0)として、ハイの8ビットを第2バイト(オフセット+1)としてマッピングします。したがって、これはAL
から格納された値でCL
をロードし、var
の後にメモリに存在する何らかの値でCH
をロードします。 をvar
の後に追加すると、CH
は値13
に等しくなり、合計CX
の値は13*256 + <stored_AL>
になります。 AL
が格納されている場合は、CX = 3335
(または16進形式の0D07h
、これは2バイトの値がうまく表示されます。D
= 13,7
= 7)です。
したがって、格納された8ビット値をCX
に正しく読み込むには、8ビットから16ビットに拡張する必要があります。あなたは80386+命令セットで作業する場合、そのための特殊な指示があります:80386前にCPUの場合
MOVZX cx,BYTE PTR [var] ; zero-extend value ("unsigned" arithmetic)
MOVSX cx,BYTE PTR [var] ; sign-extend value ("signed" arithmetic)
あなたは、このような値を計算する必要があるが、1つの可能な方法は次のとおりです。
XOR cx, cx ; clear all 16bits of CX to zero
MOV cl, [var] ; fetch only low 8 bits from memory
; CX is now zero-extended 16 bit value of [var] (like MOVZX)
MOV ch, [var] ; fetch 8 bit value into upper 8 bits of CX
SAR cx, 8 ; use right shift by 8 bits to sign-extend the value
; CX is now sign-extended 16 bit value of [var] (like MOVSX)
; this code is not optimal on 586+ CPUs, but then use MOVSX
だから、大手です"ちょうどメモリ"と "変数"の違いは、アセンブリはあなたを守りませんし、変数以外のメモリを読み書きできるようになります。正しいコードを書いてデータサイズについて考えることができます。メモリ。さらに、手動ですべてのポインタを計算します。つまり、ワードの配列(16ビットの値)を作成する場合は、正しいバイトアドレスを計算するためにインデックスを* 2でスケールする必要があります(C/C++はポインタの数式をつまり、あなたは[i]だけで、* 2はコンパイラによって内部的に行われます)。
私は、特定の場所に結びついていない論理エンティティとして、コンパイラと同じように変数を考えるのが好きです。変数は関数のある部分ではレジスタに、他の部分ではメモリに格納されます。私は本当にラベルを持つ静的ストレージを記述するために "変数"を使用するという共通のasm用語を嫌います。あなたが変数をレジスタに保持することについて話していなくても、それに対して議論する+1。 –
"変数値"あなたの '変数'の定義を表示します。 "ユーザー入力値"どのようにこの変数を入力していますか? –
アセンブリ言語やインラインアセンブリ言語について話していますか? –
私は次のコードを持っています 。データ var DB? メインPROC MOV ah、01 INT 21H ;値をAlレジスタからvarという名前の変数に移動しました MOV var、Al ;次に、私は以下のようにcxを初期化しました MOV Cx、var – Tania