2014-01-31 18 views
3

我正在設計一個簡單的玩具指令集和伴隨的模擬器,我試圖找出支持哪些指令。在算術的方式,我目前有無符號加,減,乘,除。然而,我似乎無法找到對以下問題的明確答案:哪些算術運算符需要簽名版本,哪些是無符號和二進制補碼簽名版本?哪些算術運算在無符號和二進制補碼的數字上是相同的?

因此,例如,二進制補碼中的1111等於-1。如果你給它加1並假裝它是一個無符號數,你會得到0000,即使把它想成-1也是正確的。但是,這是否適用於所有數字?對於其他三種操作(減法,乘法,除法)呢?

謝謝!

回答

2

對於有符號和無符號2s補碼,加法和減法是相同的,假設你要處理大多數CPU的正常方式的上溢/下溢,即只是環繞。乘法和除法是不同的。因此,無論簽名如何,您只需要一個附加例程和一個減法例程,但需要單獨的帶符號和無符號乘法和除法。

+2

[非擴展乘法結果對於有符號和無符號類型都是相同的](http://stackoverflow.com/q/14063599/995714) –

0

您的所有操作都需要溢出檢查,否則在某些情況下會返回不正確的值。這些檢查的未簽名版本與簽名版本不同,因此您需要單獨實施每個例程。

+1

由於這是一個指令集仿真器,我期望整數溢出/下溢會以通常的方式運行,即以2^N模爲模,所以加法和減法對於有符號和無符號都是相同的。 –

+0

真正的指令集通常處理這種情況的方式是通過使用多個標誌來檢測不同類型的溢出。 – plugwash

0

加法,減法和乘法是提供相同的:

  1. 你的輸入和輸出具有相同的尺寸
  2. 你的上溢出的行爲是環繞模2 Ñ

司不同。

許多指令集在輸出大於輸入時提供乘法運算,這些對於有符號和無符號也是不同的。

此外,如果您使用C語言編寫仿真器,則需要注意某些語言的錯誤特徵。

  1. C中有符號算術的溢出是未定義的行爲。要獲得可靠的模2 n行爲算術必須使用無符號類型執行。
  2. C會將小於int的類型提升爲int。需要非常小心,以避免這種促銷活動(在計算開始時加入0u或乘以1u是一種方式)。
  3. 從無符號類型到簽名類型的轉換是實現定義的,我見過的實現做了明智的事情,但可能有一些沒有。