汇编 编程实现从键盘输入三位以内的十进制负数_macOS上的汇编入门(二)——数学基础...
在正式介紹匯編語言之前,我會先用幾篇文章講一些數學基礎和硬件基礎。如果讀者已經具備了一定的知識基礎,可以直接跳過這些文章去匯編語言部分。
二進制,八進制與十六進制
在計算機底層的軟件層面,我們通常采用二進制,八進制或十六進制來記錄數字,其中最常用的是十六進制。所謂
進制,就是從0開始數,逢 進1. 比如說二進制,就是從0開始數,到1,然后到2的時候進1變成10. 八進制也是類似,但是到了十六進制就犯了難,我們的數字只有0到9這十個,并不能表示出16個呀,于是,我們默認使用了a到f這六個字母來分別表示10到15這六個數。也就是說,十進制數10對應的十六進制數是a, 十進制數26對應的十六進制數是1a. 在計算機底層,通常用0x開頭表示十六進制,用0開頭表示八進制,而沒有前綴來表示十進制。因此,比如說以下的匯編代碼(并不需要理解實際含義)movq $0x1a, %rax與
movq $26, %rax相同。
十進制數與十六進制數的轉化可以在搜索引擎上找到,這里不再贅述。而八進制,十六進制數與二進制數的轉換則十分簡單。一個八進制數的一位代表一個二進制數的三位,比如說八進制數的一位5就代表二進制數的三位011; 同理,一個十六進制數的一位就代表二進制數的四位。因此,十六進制數0x2000001就代表二進制數0010000000000000000000000001.
我們知道,之所以使用二進制數,是因為計算機底層采用高電平/低電平這種方法來表示數。那么,我們為什么要使用八進制、十六進制呢?我們知道,如今的計算機大多采用64位系統,意思是說,任何一個地址都是一個64位二進制數。那么,如果我們只采用二進制來表示一個地址,那么得有64個0或者1, 這不僅讓我們看花眼了,而且也極大的浪費了電腦的顯示資源。而剛才講到的十六進制數則幫我們解決了這個問題。我們知道,十六進制數的一位對應二進制數的4位。因此,一個$n$位二進制數,只需要
位十六進制數即可。也就是說,我們要表示64位的地址,只需要16位十六進制數即可。補碼
進制問題解決了在計算機底層軟件中數的表示問題,接下來還需要解決的是記錄問題,也就是說,如何把數實際存儲在64位寄存器中。我們想要解決兩個問題:
- 如何記錄負數
- 可以使用加法器計算減法么
天才般的先行者,使用了補碼來一舉解決了這兩個問題。
想要解決第二個問題,一個想法自然出現了,既然
, 那可以在加法器中輸入一個正數和一個負數來實現減法呀。然而,我們知道,在計算機中,一個存儲單位存儲的數據大小是有上限的。比如說在64位CPU中,每個寄存器有64位,因此可以存儲64位二進制數。因此,在CPU的加法器中,實際上使用了模
加法。也就是說,加法器做的,就是對于輸入的兩個64位二進制數 和 , 輸出64位二進制數 .因此,我們只有找到合適的將負數記錄成64位二進制數的方法,才能將加法器轉化為減法器。
注意到
而由于
是64位二進制數,因此, 必然是一個正數,而正數的記錄方法我們是知道的。因此,我們可以使用 來記錄 , 其參與的減法就可以變成相應的加法。但是,還有一個細節需要注意。比如說,我們想要記錄的二進制數是0xfffffffffffffffe, 那么根據剛剛討論的,我們可以將其記錄為0x1. 這就出現了問題,如何區分0x1和0xfffffffffffffffe呢?我們采用這種方法只是為了方便減法,并不打算將正數和負數混同啊。
因此,在實際操作中,當出現負數時,能夠允許的負數的絕對值最大值是
. 換句話說,其記錄值最高位0表示正數,1表示負數。這種記錄方法叫做補碼。也就是說,對于小于 的正數,采用其二進制表示為其實際記錄;對于不低于 的負數,將其加上 后的正數的二進制表示為其實際記錄。如果采用補碼,那么可以表示 的整數。因此,采用補碼記錄的數稱為有符號整數。反之,如果直接使用其二進制表示為其記錄的話,那么只能表示 的整數。因此,這種數的記錄形式稱為無符號整數。邏輯運算
除了加減乘除以外,二進制數還有獨特的運算——邏輯運算。分別是與(and), 或(or), 非(not)和異或(xor). 與或非大家都很熟悉了,異或就是當且僅當兩個操作數不同時輸出1, 相同時輸出0.
可以在哪看到這系列文章
我在我的GitHub上,知乎專欄上和CSDN上同步更新。
上一篇文章:macOS上的匯編入門(一)——引言
下一篇文章:macOS上的匯編入門(三)——硬件基礎
總結
以上是生活随笔為你收集整理的汇编 编程实现从键盘输入三位以内的十进制负数_macOS上的汇编入门(二)——数学基础...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sob攻略超详细攻略_重庆旅游攻略~超详
- 下一篇: python对象点方法_python对象