2016-07-05 9 views
5

MASM 14.0を使用してアセンブルしています。以下のコードの出力と混同しています。ASMは、算術演算が符号付きまたは符号なしであることをどのように知っていますか?

TITLE Exercise 4 from chapter 4 

; Author : Saad Ahmed 

INCLUDE Irvine32.inc 

.code 
main PROC 

mov eax, 0 
mov al, 255 
add al, 1 
call DumpRegs  ; Display registers 

mov al, 127 
add al, 1 
call DumpRegs  ; Display registers 

exit 
main ENDP 
END main 

両演算が255と127

しかし、CPUは符号なし整数として、最初の操作255を処理し、あなたが追加したときにどうなるキャリーフラグを設定された符号なし整数で行われます符号なしの255

完全ステータスフラグに1がCF = 1、SF = 0 ZF = = 0 AF = 1 PF = 1 EAXと1 0

としてではなく、第2の操作が考慮〜127でありますオーバーフローフラグを設定しているときには符号付き整数でなければなりません。 +127に1を加えると起こります。

完全ステータス・フラグは、当該CPUが最初の操作があったと判定しない方法である0

としてEAXと= 1 AF = 1 PF = 0 CF = 0 SF = 1 ZF = 0であります署名されていない255で行われ、もう一方は符号付き整数で行われましたか?

+0

add/subは、符号なしと2の補数で同じです。 [キャリーとオーバーフローの条件/フラグの理解](http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt)を参照してください。それは[x86タグwiki](http://stackoverflow.com/tags/x86/info)のものです。 –

答えて

5

2つの補完については、CPUが知る必要がないという点で優れています。

符号なしバイトの加算だけです。

255 + 1が8ビット(当然)に収まらないため、キャリーフラグが設定されています。

オーバーフローフラグは、両方のオペランドのMSBが0で、出力のMSBが1であることを示します。の場合、を符号付き算術とみなした場合、オーバーフローしています。それを符号なし算術と見なすならば、フラグを無視するだけでよい。 this wikipedia articleを参照してください。

+3

加算と減算で真...乗算と除算には、符号付きと符号なしの命令があります。 –

+0

ありがとう!はい、私は研究し、私はCPUが一連のルールを使用して算術演算の後にすべてのステータスフラグを設定したと思います。どのフラグが適切か、無視するフラグを決定する必要があります。あなたが言ったように、私は上記の演算符号なし算術を考えていたので、私はフラグを無視する必要があります。 – Saad

+1

@ AdamD.Ruppe:IMULとMULの場合、両方とも符号付きおよび符号なしの値で操作できます。 IMULは、一般にMULのマルチオパント形式とみなされます。 –

9

2の補数を使用して加算(および減算)する場合は、論理に関する限り符号付きまたは符号なしという概念はありません。必要な符号拡張のために乗算し、除算します。

3ビットの数値の組み合わせをすべて000から111にして、3ビットの数値のすべての組み合わせに追加します。もしあなたが手でやりたいのであれば、プログラムを書いてください。または、コーナーケースを実行します。各オペランドは、2つの補数を使用して符号付きまたは符号なしとして調べられます。同じ追加が機能することに注意してください。 1 + 110 = 111。今や1 +(-2)= -1か1 + 6 = 7だった。

キャリーフラグはUNSIGNEDオーバーフローです.VフラグはSIGNEDオーバーフローです。そのため、両方の値を計算する理由は、署名付きかどうかを知っているユーザーが正しい条件を選択できるためです。そして、それ以上であるか等しいかそれ以上であれば、あなたはジャンプをサインしています。

2つの補数がすべて機能するのは美しいです。

拡張に署名する必要があるため、乗算(および除算)は異なります。バイナリでの乗算は、あなたが考えてみれば

abcd 
* 0011 
======= 
    abcd 
    abcd 
0000 
0000 
======= 

ことで、少し美しい機能を持っている1または0のいずれかであるあなたが1または0のいずれかによって上位数を乗算しているので、あなたはそれがシフトしたり追加してくださいいけない。しかし、非常にすぐにあなたがオーバーフローすることに気付くこともあります。私は小学校から、n^x * n^y = n ^(x + y)を知っています。レジスタがZビット幅の場合、オペランドの最上位ビット位置はZを超えてはいけません。それ以外の場合は、オーバーフローします。 4ビット0010 * 0010は動作するはずですが、0010 * 1000はオーバーフローします。正しい方法は、結果がオペランドの2倍であることです。

1111 * 0010を掛けたいのですが?基本的に

0000 
    1111 
    0000 
+0000 
======== 
0011110 

待機ある

15(0b1111)または-1(0b1111)ことでしたか? -1 * 2 = -2は、我々が上記の得たものではありませんこれは、我々は左

11..1111 
*00..0010 
=========  
00000000 
1111111 
000000 
00000 
========= 
11111110 

オフ拡張し、トスビットに署名する必要があり、それがために正しい答えを与える乗算署名しないために符号なし乗算を行いました2つの4ビットレジスタ1111および0010の符号付き乗算。

加算は、1つの列のみを扱うために機能します。各列にはキャリーイン、2つのオペランドには結果、キャリーアウトがあります。そして、あなたはあなたが望むだけ幅広くカスケードすることができます。 1ビットの場合、0と1があります。ゼロはプラスまたはマイナスゼロではなくゼロです.1は+1または-1のいずれかです。複数の列を組み合わせて作業する方が簡単ですが、実行できます。加えてのためにキャリーは、私はそれは、オペランドBをオペランド実行し、署名したその最後のケースであふれ、それがあるだった

00 00 0 + 0 = 0 
01 01 0 + 1 = 1; 0 + (-1) = -1 
10 01 1 + 0 = 1; (-1) + 0 = -1 
11 10 1 + 1 = 0 unsigned overflow. -1 + 1 = 0, 1 + -1 = 0, -1 + -1 = 0 signed overflow 

技術的には、すべての署名のものを結果として表現する必要がいけないので、0であります任意の数のビットに対して処理する特別な場合は、3ビットレジスタをとる100 + 100 = 000 + 1の実行は、4 + 4 = 0の符号なしオーバフローであるか、または-4 + -4 = 0である署名されたオーバーフロー?これは、数ビットを使用して、1の問題の場合とすべてゼロの組み合わせを通過するときに、より簡単に表示される理由です。

符号付きオーバーフローは、最上位列のキャリーインがキャリーアウトと一致しない場合です。符号なしオーバーフローは、msbitのキャリーが1であるときです。

論理での減算は加算によって行われます。私たちは小学校からa - b = a +(-b)を知っています。そして、2つの補数を使って負数を取るプログラミングクラスから、反転して追加します。うーん、うまくいくのは、2番目のオペランドを反転させ、lsbitのキャリーを逆にして1にしたり、逆にして1を加えることができます。それがその仕組みです。借りていることを示すためにaluから出て行くことが逆転することがあります。あなたはこれを理解するためにフラグの組み合わせを見なければならない、いくつかのプロセッサはいくつかの実行を逆転させない。あなたのISAがその指示を持っているならば、時々借りて引くことから告げることができます。

私は知っていますTL:DR ...あなたが尋ねた以上のものをカバーしています。

+0

もし乗算がNビットのNビットであれば、右に拡張する必要はありませんか?したがって、それは標識特有ではない。 1111 * 0010 = 1110署名されていない場合はオーバーフローですが、署名されている場合は正解です(ダム運)。 –

関連する問題