2017-09-07 6 views
-1

変数値でCxレジスタを初期化できますか? NOの場合、どのように動的にユーザ入力値とCxとを初期化する場合ステートメントワークを完璧にするには?

MOV Cx, varaible 

下に示す など?助けてください!

+2

"変数値"あなたの '変数'の定義を表示します。 "ユーザー入力値"どのようにこの変数を入力していますか? –

+0

アセンブリ言語やインラインアセンブリ言語について話していますか? –

+0

私は次のコードを持っています 。データ var DB? メインPROC MOV ah、01 INT 21H ;値をAlレジスタからvarという名前の変数に移動しました MOV var、Al ;次に、私は以下のようにcxを初期化しました MOV Cx、var – Tania

答えて

3

名前についてではなく、精神的なイメージについてです。アセンブリには変数はありません。

マシンには、レジスタ、メモリ、アドレス、および命令付きメモリへのアクセスだけがあります。 変数は、プログラマの論理的な構成要素であり、プログラマは、そのような方法でコードを書くことに決めました。つまり、メモリを「可変」として使用します。しかし、彼がそうしないと決めた場合、または間違いを犯すと、それは変数として動作しません。マシンは気にしません。あなたのコードでたとえば

、あなたは.dataセクションの「変数」のためのメモリを割り当てる:

.Data 
var DB ? 

これが効果的にメモリに対応している、シンボルvarに変換します。また、.dataセクションの1バイトを予約します。したがって、次にそこに着陸するように定義されたものは、その後に割り当てられます。次の行に追加する場合はvar2 DB 13var2のアドレスはvar + 1になります。また、このように、同じアドレスで複数のシンボルを作成することができます

.Data 
var: 
var2: 
    DB ? 

を両方varvar2シンボルが同じメモリアドレスを指すように定義しています。

それはまだあなたの「変数」精神的な画像のように見えるかもしれませんが、これに対応しているので、私は「ちょうどメモリ」と「変数」の間に別の違いを紹介します:

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はコンパイラによって内部的に行われます)。

+1

私は、特定の場所に結びついていない論理エンティティとして、コンパイラと同じように変数を考えるのが好きです。変数は関数のある部分ではレジスタに、他の部分ではメモリに格納されます。私は本当にラベルを持つ静的ストレージを記述するために "変数"を使用するという共通のasm用語を嫌います。あなたが変数をレジスタに保持することについて話していなくても、それに対して議論する+1。 –

関連する問題