编程逆向基础
第一章 進制
引言:
進制跟我們生活是息息相關(guān)的,比如 時鐘,星期 等,那么計算機也離不開進制,計算機是通過二進制進行操作和運算的。
我們?yōu)槭裁匆獙W習進制?
方便我們了解計算機,了解計算機的運行,為以后的學習打下基礎。
什么才是正確的學習方法?
忘掉呆板的十進制!說到進制,其時大家都會,只是生活中的運用把其它的進制都丟棄了,只留下十進制,這一章主要是帶我們了解各種進制,找回應有的記憶。
本章必須要掌握的知識點:
本章常犯的錯誤:
4.數(shù)據(jù)進制
本節(jié)主要內(nèi)容:
老唐語錄:
現(xiàn)在請一個同學上來寫出 10 進制的 0-100
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
100
大家看著上面的的數(shù)字說一句話:
小陶 say: 有 101 個數(shù)
小胡 say: 十進制從 0 到 100。
……
其實這就是小學入學考試,只要寫出 0-100 就可以參加學習我們的課程。
下面我來給十進制下個定義:
十進制是由 0、1、2、3、4、5、6、7、8、9 十個符號組成,逢十進一。
你們給九進制下個定義:
九進制定義:九進制是由 0、1、2、3、4、5、6、7、8 九個符號組成,最小是 0,最大是 8,逢九進一。
練習:
用九進制寫出十進制的 101 個元素:
0 1 2 3 4 5 6 7 8
10 11 12 13 14 15 16 17 18
20 21 22 23 24 25 26 27 28
30 31 32 33 34 35 36 37 38
40 41 42 43 44 45 46 47 48
50 51 52 53 54 55 56 57 58
60 61 62 63 64 65 66 67 68
70 71 72 73 74 75 76 77 78
80 81 82 83 84 85 86 87 88
100 101 102 103 104 105 106 107 108
110 111 112 113 114 115 116 117 118
120 121
現(xiàn)在給七進制下個定義:
七進制是由 0、1、2、3、4、5、6 七個符號組成,最小是 0,最大是 6,逢七進一。
練習:
用七進制寫出十進制的 101 個元素:
0 1 2 3 4 5 6
10 11 12 13 14 15 16
20 21 22 23 24 25 26
30 31 32 33 34 35 36
40 41 42 43 44 45 46
50 51 52 53 54 55 56
60 61 62 63 64 65 66
100 101 102 103 104 105 106
110 111 112 113 114 115 116
120 121 122 123 124 125 126
130 131 132 133 134 135 136
140 141 142 143 144 145 146
150 151 152 153 154 155 156
160 161 162 163 164 165 166
200 201 202
現(xiàn)在給十一進制下個定義:
十一進制是由 0、1、2、3、4、5、6、7、8、9 還差一個符號,用 X 也行,用 A 也行,
共十一個符號組成,最小是 0,最大是 X(或 A),逢十一進一。
練習:用十一進制寫出十進制的 101 個元素:
0 1 2 3 4 5 6 7 8 9 A
10 11 12 13 14 15 16 17 18 19 1A
20 21 22 23 24 25 26 27 28 29 2A
30 31 32 33 34 35 36 37 38 39 3A
40 41 42 43 44 45 46 47 48 49 4A
50 51 52 53 54 55 56 57 58 59 5A
60 61 62 63 64 65 66 67 68 69 6A
70 71 72 73 74 75 76 77 78 79 7A
80 81 82 83 84 85 86 87 88 89 8A
90 91
現(xiàn)在給三進制下個定義:三進制是由 0、1、2 共三個符號組成,最小是 0,最大是 2,逢三進一。
練習:
用三進制寫出十進制的 101 個元素:
0 1 2
10 11 12
20 21 22
100 101 102
110 111 112
120 121 122
200 201 202
210 211 212
220 221 222
1000 1001 1002
1010 1011 1012
1020 1021 1022
1100 1101 1102
1110 1111 1112
1120 1121 1122
1200 1201 1202
1210 1211 1212
1220 1221 1222
2000 2001 2002
2010 2011 2012
2020 2021 2022
2100 2101 2102
2110 2111 2112
2120 2121 2122
2200 2201 2202
2210 2211 2212
2220 2221 2222
10000 10001 10002
10010 10011 10012
10020 10021 10022
10100 10101 10102
10110 10111 10112
10120 10121 10122
10200 10201
其實學計算機很簡單,就是扳著手指頭數(shù),如果不是數(shù)出來,是算出來的都是錯誤的想法。數(shù)的本質(zhì)是數(shù)出來的。
比如:2+2 = 4 我們可以用手指頭一個一個數(shù)出來。
課后理解:
各種進制如表 1-1:
表 1-1:1-11 進制表示
進制 實例
1 0,00,000,0000,00000,000000…
2 0,1,10,11,100,101,110,111,1000…
3 0,1,2,10,11,12,20,21,22,100…
4 0,1,2,3,10,11,12,13,20,21,22…
5 0,1,2,3,4,10,11,12,13,14,20…
6 0,1,2,3,4,5,10,11,12,13,14…
7 0,1,2,3,4,5,6,10,11,12,13,14…
8 0,1,2,3,4,5,6,7,10,11,12,13…
9 0,1,2,3,4,5,6,7,8,10,11,12…
10 0,1,2,3,4,5,6,7,8,9,10,11,12…
11 0,1,2,3,4,5,6,7,8,9,A,10,11…
進制其實是 N 種符號組成的。
課后總結(jié):
進制是由元素組成的,N 進制就是有 N 個元素組成,逢 N 進一
課后練習:
1.2 進制運算
本節(jié)主要內(nèi)容:
老唐語錄:
十進制是大家小學時就會的:
0,1,2,3,4,5,6,7,8,9
那么九進制大家也應該都會:
0,1,2,3,4,5,6,7,8
十進制可以加減乘除,那么九進制照樣可以加減乘除,直接算出結(jié)果,十一進制也可以。既然小于十進制都會,大于十進制都會,那就是說 N 進制都會。難道 N 進制都會,唯獨不會二進制嗎?
既然你們都會的話,書上為什么還要教二進制呢?還用進制間轉(zhuǎn)換嗎?你們可以看一下書上,有十進制轉(zhuǎn)二進制,二進制轉(zhuǎn)十進制,不是多此一舉嗎?三進制可以直接算出結(jié)果,九進制也可以直接算出結(jié)果,為什么二進制不可以呢?任何一種進制,他自身就是一個完美的體系結(jié)構(gòu),直接能加減乘除開方。
練習:
九進制加法:
7+8=16
九進制根本不需要去轉(zhuǎn)換,可以直接算出結(jié)果,十進制也是,和其他進制沒有關(guān)系,自成一個體系結(jié)構(gòu)。任何進制都可以直接加減乘除。那么,同樣的,三進制,二進制,八進制,十六進制都是一個完美的體系結(jié)構(gòu),都可以自己加減乘除,直接算出結(jié)果,如果誰去轉(zhuǎn)換成二進制,那說明不懂。二進制可以直接加減乘除算結(jié)果,把結(jié)果拿來用就可以了。比如:你說你有“110”塊錢不行嗎?非要用十進制的嗎?如果需要加減,可以直接加減,九進制可以直接加減,為什么二進制不能呢?既然加減乘除都可以,為什么還要去轉(zhuǎn)換呢?現(xiàn)在懂了沒有?大家理解所有進制了嗎?
小桃 say:“懂了。”
小胡 say:“會了。”
二進制就是由 0 和 1 共兩個符號組成,最小是 0,最大是 1,逢二進一,就學完了。
那現(xiàn)在我們給 N 進制下個定義:
N 進制就是由 0、1、2、3、4……N-1 共 N 個符號組成,逢 N 進一。
我們說過了,人類只會數(shù)數(shù),不會加減,所以說我們用進制不能用的太大,因為十進制有十個符號,相互之間加減是我們能記住的。二進制就更簡單,只有兩個符號,兩個之間相互加減,都是可以記住的,為什么計算機用二進制?因為二進制最簡單,需要記住的東西最少,人類不會計算,當然計算機更不會計算。所以說他只能用最簡單的記憶方法來算,因為十進制需要記住的符號太多了。
比如在十進制中,5+4=9,2+7=9,1+8=9,3+6=9,2+8=10,兩兩相加,符號太多
了,很麻煩,相比較而言,二進制要簡單的多。嚴格的說,他只有兩個結(jié)果 0 和 1,所以非
常簡單。而其他進制太復雜,三進制,四進制,五進制,六進制都很復雜,所以說基本都不
用。人類最常用的是十進制,因為人類有十個手指頭,數(shù)起來很方便。最方便的數(shù)數(shù)工具,
就是手指。人類天生就會使用十進制,當然也有民族使用五進制的,因為五進制數(shù)起來也很
方便,一個手五個手指頭,一個手專門去數(shù)。現(xiàn)在大家都懂了進制了吧?
練習:
用一百進制從 0 寫到十進制的 101?現(xiàn)在大家自己在紙上寫,或者誰上來寫。
小劉 say:“后面咋整?”
老唐 say:“隨便你,不是學過了嗎?九進制會了,十進制會了,十一進制會了,也就
是說大于十進制的都會。小于十進制的都會。難道就不會一百進制嗎?”
小李 say:“用什么來表示?”
老唐 say:“隨便。”
小桃 say:“寫到一百零一只進了一次”
老唐 say:“是啊。”
其實我們學到 0,1,2,3,4,5,6,7,8,9 是阿拉伯人的符號。零,一,二,三……
是中國人的符號,僅僅是個符號而已。
練習:
用一進制從 0 寫到十進制的 20,結(jié)繩記事用的就是一進制。
0
00
000
0000
……
陰陽八卦就是二進制,宇宙中最和諧最完美的進制就是二進制。有和無,白和黑,無和
點(點可以構(gòu)成畫,畫可以構(gòu)成所有)
練習:
用二進制從零寫到十進制的 100。
0 1
10 11
100 101
110 111
1000 1001
1010 1011
1100 1101
1110 1111
10000 10001
10010 10011
10100 10101
10110 10111
11000 11001
11010 11011
11100 11101
11110 11111
100000 100001
100010 100011
100100 100101
100110 100111
101000 101001
101010 101011
101100 101101
101110 101111
110000 110001
110010 110011
110100 110101
110110 110111
111000 111001
111010 111011
111100 111101
111110 111111
1000000 1000001
1000010 1000011
1000100 1000101
1000110 1000111
1001000 1001001
1001010 1001011
1001100 1001101
1001110 1001111
1010000 1010001
1010010 1010011
1010100 1010101
1010110 1010111
1011000 1011001
1011010 1011011
1011100 1011101
1011110 1011111
1100000 1100001
1100010 1100011
1100100
練習:
九進制加減法
765-567
注:借一位是 9
練習:
七進制加法
654+321
進制的加減法都會了吧,現(xiàn)在我們來練習乘法
練習:
十進制乘法
8*9
練習:
五進制乘法
3*4
進制間的乘法都會了吧,那現(xiàn)在這道題給你們 10 分鐘做出來
練習:
十一進制乘法
789A*A987
注:這個運算比較復雜,因為我們沒有掌握它的乘法表,我們只知道十進制乘法表。現(xiàn)
在我們來編寫其他進制乘法表。
二進制
11 = 1
三進制
11 = 1
21=1 22=11
四進制
11=1
21=2 22=10
31=3 32=12 33=21
五進制
11=1
21=2 21=4
31=3 32=11 33=14
41=4 42=13 43=22 44=31
六進制
11=1
21=2 22=4
31=3 32=10 33=13
41=4 42=12 43=20 44=24
51=5 52=14 53=23 54=32 55=41
七進制
11=1
12=2 22=4
13=3 23=6 33=12
14=4 24=11 34=15 44=22
15=5 25=13 35=21 45=26 55=34
16=6 26=15 36=24 46=33 56=42 66=51
九進制
11=1
21=2 22=4
31=3 32=6 33=10
41=4 42=8 43=13 44=17
51=5 52=11 53=16 54=22 55=27
61=6 62=13 63=20 64=26 65=33 66=40
71=7 72=15 73=23 74=31 75=38 76=46 77=54
81=8 82=17 83=26 84=35 85=44 86=53 87=62 88=71
十二進制
11=1
21=2 22=4
31=3 32=6 33=9
41=4 42=8 43=10 44=14
51=5 52=a 53=13 54=18 55=21
61=6 62=10 63=16 64=20 65=26 66=30
71=7 72=12 73=19 74=24 75=2b 76=36 77=41
81=8 82=14 83=20 84=28 85=34 86=40 87=48 88=54
91=9 92=16 93=23 94=30 95=39 96=46 97=53 98=60 99=69
a1=a a2=18 a3=26 a4=34 a5=42 a6=50 a7=5a a8=68 a9=76
aa=84
b1=b b2=1a b3=29 b4=38 b5=47 b6=56 b7=65 b8=74 b9=83
ba=92 bb=101
課后理解:
小陶 say:
我的理解:
我們可以通過十進制的乘法,從中摸索出規(guī)律:
456456
先進行個位相乘:66=36,進 3 余 6,等等,我們怎么知道 66=36? 是通過 99 乘
法表得到的。同樣除法也是如此。找到這個規(guī)律,我們就清楚接下來該做什么了:
七進制:
456456=?
我們把七進制的乘法表寫出來:
11 = 1
12 = 2
22 = ?在 12 的基礎上加 2 為 4
23 = ?在 22 的基礎上加 2.
這樣,乘法演變成加法。所以很快得出七進制的乘法表:
11 = 1
12 = 2 22 = 4
13 = 3 23 = 6 33 = 12
14 = 4 24 = 11 34 = 15 44 = 22
15 = 5 25 = 13 35 = 21 45 = 26 55 = 34
16 = 6 26 = 15 36 = 24 46 = 33 56 = 42 6*6 = 51
小胡 say:
計算機只會加法,現(xiàn)實中為了計算方便所以建立了乘法表。
課后疑問:
111-111 = ?
有的人說等于 0。那么,如果我使用 0 作為一進制的符號:
00 + 000 = 00000
000 - 00 = 0,
那么 000 - 000 = ?
說明:
其實我們不用糾結(jié)于算數(shù)的結(jié)果,111-111 = 空,這個空可以用其他符號代替,只要不
是該進制使用過的符號即可.
課后總結(jié):
課后練習:
1.3 十六進制與數(shù)據(jù)寬度
本節(jié)主要內(nèi)容:
老唐語錄:
進制現(xiàn)在理解了嗎?
在自然界都只有二進制存在。有二進制已經(jīng)足夠了,完全沒必要有其他進制。其實自然界也是按這個發(fā)展的。學過生物的都知道細胞的分裂。沒有說細胞一次性分成三個細胞,四個細胞的吧?只有一個細胞一次分成兩個細胞,兩個細胞再分成四個細胞,然后八個細胞。無論是單細胞還是多細胞,都是一個變二個,兩個變四個,都是按二進制來的。呈二進制的指數(shù)增長。而不是十進制的指數(shù)增長,更不是其他進制的。十進制只是人類特殊創(chuàng)造的。二進制有個問題,雖然很方便。也可以做很大,你看二進制書寫很麻煩。
1111111111111111111111111111111,也就是說二進制表示現(xiàn)實生活中的數(shù),比如你家里多少錢的時候,也并不需要多少位。二進制表示生活中的數(shù)也是很短的,并不是很長。32 位,已經(jīng)很大了,4 個 G。我們說人類特別喜歡用十進制去寫。比如 256,使用二進制寫會很長(100000000B),你用二進制寫會很長。既然你用二進制寫太長了,要書寫簡化,我們書寫簡化一下二進制。比如二進制我們書寫:10101010111010
太長了,我們兩位兩位的書寫,我們用個符號來表示,隨便一個符號,比如用 B 來表示。有沒有發(fā)現(xiàn),兩位兩位的書寫,最多出現(xiàn)四種可能是吧,00,01,10,11。這四種可能,那么兩位兩位的書寫很方便啊,隨便用四個符號代替就行。雖然說二進制有點長,但二進制畢竟是宇宙中最簡單的。人類畢竟不習慣,為什么?因為太長。我們兩位兩位的書寫。兩位最多要求0,1,2,3.再沒別的值了吧。也就是說只要定義四種符號去書寫他就可以了。那我們還是覺得長,那好。我們?nèi)蝗坏臅鴮憽D侨蛔疃嗟目赡苣?#xff1f;100,101,110,111 最多只有八種,那我們用 A,B,C,D,E,F,G,H,去表示。010 在這是 C 是吧。111 是 H是吧,010 是 C,101 是 F,這個 010 是 C,CFCHC。那好了,我們也可以同理,我們照樣可以四位四位的書寫。也可以五位五位的書寫。六位六位的書寫,七位七位的書寫。但是有個問題有沒有發(fā)現(xiàn)。我們四位四位的書寫,就會發(fā)現(xiàn)一個問題,符號會越來越多。1000,1001,1010,1011,1100,1101,1111,I,J,K,L,M,N,O。不需要排順序,只要你使用這十六種符號表示這十六種值就可以。那好了,我們查表。1010,是 K,1011是 L,1010 是 K,0010 是 C,CKCK。導致多位多位的書寫。整體變得很短了。問題就是這邊要記的符號越來越多了。是不是啊?那當然你還可以五位五位的書寫。五位五位書寫更短了是吧?那現(xiàn)在要記多少個符號啦,每多一位,符號要增一倍。兩位兩位的書寫只要記 4個符號。三位三位書寫八個符號。四位四位書寫 16 個符號。五位五位書寫 32 個符號。六位六位書寫 64 個符號。如果七位七位書寫呢?那就 128 個符號了。那為什么當初不讓你們用一百進制,那就是符號太多,記不住。人類只會記和數(shù),不會算。二進制的書寫對于人類來說畢竟是太長了,所以我們采用簡單的方法。就是說,兩位兩位,三位三位,四位四位,或者五位五位,六位六位,七位七位的書寫。到底你喜歡多少位書寫呢?看你喜歡記的符號多還是少呢?比如:7 位 7 位的書寫,你要記 128 個符號;八位八位的書寫,你要記 256個符號。如果你基本功扎實,記得這么多符號,那你寫的時候就要容易一點。比如:你的文學功底比較深厚,字學的比較多,詞語比較多,成語比較多,那你寫的文章就漂亮,并且簡短,精煉。那這樣,只要你符號記得足夠多,那么你書寫起來就簡短精煉。當然,你符號記得越少,你寫的就越長。“記流水賬嘛。”如果你字都不會寫,就是寫的再長,都是反復的這么說來說去,沒什么內(nèi)涵,也沒什么文采。二進制有兩種,二進制本身是一種,還有一種是二進制的書寫形式。書寫形式有很多種:一位一位的書寫,兩位兩位的書寫,還是三位三位的書寫,看你書寫形式。我們現(xiàn)在書寫 A,B,C,D,我是兩位兩位的書寫,自然這個 D 是 11,C 是 10,B 是 01,
A 是 00。這兩種書寫形式表示的含義是一樣的。上面是書寫形式,下面是本質(zhì)形式。當然本質(zhì)形式也是其中一種書寫形式。也就是說一個漢字他可以有草書,隸書。當然一個二進制也有很多種書寫形式。本身二進制這東西只有一個,但是名字有很多種。比如:一個人有幾個名字,一個地方有幾個名字,一個物體拍照片可以拍很多張,但是你都認識他。當然了,
你也可以一位一位的書寫,我用 A 表示 0,B 表示 1,就是 BBABBAAA……這也是二進制的
書寫形式。你可以另外定義兩個符號,未必要用用原來的 0 和 1。另定義兩個符號用 A 和 B
兩個符號。也可以兩位兩位的書寫,用 ABCD 來表示。或者是三位三位的書寫。
那到底是幾位幾位的書寫更方便呢?
其實很簡單。就是因為在全世界阿拉伯數(shù)字的符號最簡單,我們就不應該用 ABCD 這個符號去表示。我們到底使用 1 位 1 位,2 位 2 位還是 3 位 3 位 4 位 4 位 5 位 5 位書寫呢,很簡單,我們找這符號,這個符號不能太多,256,128,64,32,都顯得多了,就算不多,那我們討論到底多少適合,我們喜歡阿拉伯數(shù)字的符號,那我們就用阿拉伯人的符號來表示。阿拉伯人的符號太完美了,所以我們不能使用三位三位的書寫,因為會浪費兩個 8 和 9,太可惜了。所以我們一定要大于三位三位的書寫。因為我們不要浪費這個符號。就使用四位四位的書寫,才能保證把阿拉伯人的符號全部用上。那四位的書寫,少了幾個符號,那用誰的符號呢?我們發(fā)現(xiàn)其實英國人也很聰明,英國人的符號也不錯。少幾個符號我們用英國人的符號補上去。畢竟英國人沒有古印度人聰明,我們補太多的符號,不便于記憶,所以使用四位四位的書寫。這不是十六進制,這是四位四位的書寫二進制。跟十六進制沒有一點關(guān)系。你只要簡單的記住這十六個符號來表示這十六種值就可以了。
以后寫二進制四位四位的書寫:
二進制從 0000 寫到 1111
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
然后改成 16 個符號。
如果按照這種新的書寫方式,那你們發(fā)現(xiàn)如果要進位的話,要滿 16 才進位。中國古代就知道用二進制數(shù),并知道四位四位的書寫。這就是我們平時說的半斤八兩,其實就是二進制四位四位的書寫導致的結(jié)果。你們用過算盤沒有?我們平時只用下面四個珠子,上面一個珠子,為什么上面兩個珠子,下面五個珠子?這就是二進制,喜歡四位四位的書寫,最小值是 0,最大值是 15,下面加上上面值為 15,不撥的時候 0,全撥的時候 15。這就是最早的計算機。有的銀行現(xiàn)在仍然使用算盤,加減法還是算盤快,乘除法計算機快。現(xiàn)在開始練習二進制的兩種書寫方式:一位一位的書寫,四位四位的書寫。數(shù)學上的數(shù),無論多長,都能表示出來,是沒有寬度的。算盤寬度是有限的。凡是涉及到機器上的數(shù),寬度總是有限的,計算機中的數(shù)是用電路表示的,計算機成本是有限的,所以表示寬度是有限的。
這里為了書寫方便我們只寫 8 個位:
-1=0-1
00000000
-00000001
計算機在計算數(shù)之前,要規(guī)定這個數(shù)有多寬。-1 是 0xFF。
例:從 0,寫到-50。
例:寫 4 位,最大值與最小值可以交匯到一點,形成一個圓。
課后理解:
在數(shù)學運算中,數(shù)值的大小(即寬度)是沒有限制的,比如
100000*100000=10000000000。在計算機中,在對數(shù)值進行運算前要先規(guī)定其寬度,再
進行運算.比如給定的一個數(shù) 0x123456789ABC,如果規(guī)定它的寬度為 32 位(這里指的
32 通常是二進制的 32 位),那么該數(shù)值的有效值為 0x56789ABC.如果運算結(jié)果超過其寬
度將被略去,只保留有效位。
例:設給定的數(shù)值寬度為 8 位(二進制),則可以表示的最大值為 0xFF(11111111B)。
此時,0x81+0x80= 1000 0001B+ 1000 0000B= 1 0000 0001(B) = 0000 0001
(B) = 0x1。圖 1-2 顯示了計算機常用的數(shù)值寬度
如上圖所示,字節(jié)(Byte)占據(jù) 8 位二進制寬度;字(Word)占據(jù) 16 位二進制寬度;
雙字(Doubleword)占據(jù) 32 位二進制寬度;四字(Quadword)占據(jù) 64 位二進制寬度。
在計算機的數(shù)值運算中,不僅要規(guī)定數(shù)值的寬度,同樣要設置數(shù)值的符號和精確度。比
如正數(shù),負數(shù)和浮點數(shù)。針對這種情況,計算機將數(shù)值定義為有符號或無符號類型:當為有
符號類型時,最高位作為符號位,最高位為 1,表示負數(shù),反之為正數(shù),見圖 1-3:
有符號數(shù)值大小,見表 1-2:
課后總結(jié):
計算機是定寬的。
課后練習:
2,4,16 進制,每進制最大 32 位,寫出 8 個主要點
1.4 邏輯運算
本節(jié)主要內(nèi)容:
老唐語錄:
上節(jié)我們講到,計算機是定寬的
比如: 一個二進制數(shù) 1111 1111 1111 1111B
我們用四位,四位書寫的式 FFFF 這樣比較簡單
今天我們講,計算機除了算術(shù)運算外,還有邏輯運算,只有二進制才能進行邏輯運算。
邏輯運算中只有錯與對,成與敗兩個結(jié)果(也就是 0 和 1)。
或運算:
0+0=0
0+1=1
1+1=1(1+1=2 不等于 0,就是 1)
“+”等價于“或”,計算機中使用“|”符號代替。匯編語言使用“OR”代替
與運算:
00=0
01=0
10=0
11=1
“*”等價于“與”,計算機中使用“&”符號代替。匯編語言使用“AND”代替
異或運算:
0-0=0
1-0=1
0-1=1
1-1=0
“-”等價于“異或”,計算機中使用“^”符號代替。匯編語言使用“XOR”代替
三種運算在生活中怎樣存在?
說明:看圖 1-5,這是一個串聯(lián)電路圖,只有兩個開關(guān)同時按下時,燈泡才會亮。
異或運算電路如圖 1-6:
課后理解:
小陶 say:
或運算(|):只要有一個是 1,就是 1,其它為 0
與運算(&): 兩個為 1 才是 1,其它為 0
異或運算(^):相同的為 0,不同的為 1
小胡 say:
看了樓主的理解,我懂了
課后總結(jié):
二進制實現(xiàn)了邏輯運算和算術(shù)運算的統(tǒng)一。
課后練習:
1.2、4、6 進制,每個進制寫 32 位。0-FFFFFFFF
2.寫 10 個寄存器,背熟順序
第二章 寄存器與匯編指令
引言
想要了解計算機,首先要了解的便是 cpu,cpu 是計算機最核心的部件,因為計算機
的所有指令都是由 cpu 處理,而 cpu 的核心部件之一是寄存器。這一章我們就來認識一下
寄存器以及寄存器是如何工作的。
本章必須要掌握的知識點:
本章常犯的錯誤:
2.1 通用寄存器
本節(jié)主要內(nèi)容:
老唐語錄:
計算機最經(jīng)典的指令就是移動指令:mov ecx,eax;
主要記住這 8 個寄存器:
eax
ecx
edx
ebx
esp
ebp
esi
edi
mov 指令可以任意移動這 8 個寄存器。
在 mov ecx,eax 中,后面的是源,前面的是目標,中間是逗號,不區(qū)分大小寫。寄存器間相互移動。
如果計算機只有移動指令的話,那么什么事也干不了。mov 是操作碼,兩個寄存器是操作數(shù),操作碼除了 mov 之外還有很多,你可以替換:加,ADD;減,SUB;與,AND;或,OR;異或,XOR;非,NOT。
比如:add eax,ecx。當然了,操作碼不僅僅只有這幾個,還有很多很多,只要搞清楚操作數(shù)是任意兩個寄存
器,當然可以是同一個寄存器。比如 or esi,esi:將 esi“或”esi 并將結(jié)果賦給 esi。操作數(shù)除了寄存器之外,
還可以是一個數(shù),只要保證是 32 位即可。8 個寄存器是分段的。比如算盤,我們可以只用一半,或者四分之一。
eax 可以分成四部分:eax 共 0-31,其中 0-7 位叫做 AL,8-15 位叫做 AH。整個 0-15位又稱為 AX。AL:low;AH:high。ecx,edx,ebx 也是一樣的,如圖 2-1。
32 位寄存器有自己的編號,16 位寄存器也有屬于自己的獨立的編號。當然,他們是重疊的,當改變了 32 位的寄存器,相應的 16 位寄存器也會跟著改變。同樣,也有 8 位的寄存器,第 0 號 AL,第 1 號,CL,DL,BL,AH,CH,DH,BH。順序不能亂。當然還有兩個寄存器:EIP 和 EFLAGS(又稱為 EFL),8 號和 9 號寄存器,EIP 有 16 位,叫做 IP。EFL 的 16 位稱為 FL。這兩個寄存器使用相對較少。
練習:
除了 EIP 和 EFL 之外,其他寄存器都是可用的,使用 MOV,ADD,SUB……等指令做練習,比如 XOR AL,BH,后面隨便跟兩個寄存器,用逗號隔開,當然,前后寬度要一樣。而不可以是 XOR AL,BX。后面的寄存器可以改成立即數(shù)。
課后理解:
通用寄存器即 cpu 常用的寄存器。Intel 手冊給出了通用寄存器的功能:通用目的寄存器(General-Purpose Registers)主要實現(xiàn)邏輯和算術(shù)運算、地址計算和內(nèi)存指針。
步不會停歇的,之后將 16 位寄存器都擴充了一倍,于是 32 位寄存器出現(xiàn)了,當然這里只
截至 32 位,64 位和 128 位寄存器留給大家思考。
32 位通用目的寄存器的指定用途如下:
·EAX:累加器(Accumulator)
·ECX:計數(shù)(Counter)
·EDX:I/O 指針
·EBX:DS 段的數(shù)據(jù)指針
·ESP:堆棧(Stack)指針
·EBP:SS 段的數(shù)據(jù)指針
·ESI:字符串操作的源(Source)指針;SS 段的數(shù)據(jù)指針
·EDI:字符串操作的目標(Destination)指針;ES 段的數(shù)據(jù)指針
以上只是讓大家對寄存器的縮寫的含義了解一下,畢竟使用一樣東西,不明白其中的道
理,實在不高明,而且這東西是老外發(fā)明的,按中式邏輯很難猜出來。
課后疑問:
問題:EIP 在不斷變化,我們不但要有命令去操作這些寄存器,還需要區(qū)分當前用的是哪一條命令,下一次再用哪一條命令。
回答:cpu 具有判斷指令長度和預處理指令的功能。
為什么你寫的寄存器順序是 EAX,ECX,EDX,EBX……而不是 EAX,EBX,ECX,EDX……,不是更容易記住?
回答:其實我也想,可是 Intel 的技術(shù)員不這么認為,他們就是這么定義寄存器順序的。了解寄存器的順序和編號,對后面將要介紹的匯編指令和硬編碼尤為重要。
課后總結(jié):
匯編就是在“寄存器與寄存器”或者“寄存器與內(nèi)存”之間來回移動數(shù)據(jù)。
課后練習:
32,16,8 位寄存器用 mov add AND sub or xor not 演算
2.2 內(nèi)存
本節(jié)主要內(nèi)容:
老唐語錄:
快速算盤叫做寄存器。慢速的稱為內(nèi)存。其實他們的結(jié)構(gòu)差不多,都是定寬的,最重要的一點,寄存器速度非常快,價格非常昂貴,所以在 CPU 內(nèi)部。做的數(shù)量也很有限。常用的只做了 8 個:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI。內(nèi)存速度慢,很便宜,所以數(shù)量做的非常龐大。寄存器做的數(shù)量非常少,就可以為每個寄存器取個名字。而內(nèi)存數(shù)量太龐大了,沒辦法給每一個都取上名字,所以只能編號。最后重要的是內(nèi)存中寄存器的編號是32 位的。這也是我們現(xiàn)在的計算機叫 32 位計算機的主要原因。如果按寄存器的寬度是 32位的話,是不對的,因為還有很多寄存器是大于 32 位的。我們通用的 8 個是 32 位的。而內(nèi)存地址是固定的 32 位。以前的計算機之所以稱為 16 位計算機,就是因為他的內(nèi)存單元編號是 16 位的。
我們學過的指令 MOV,能操作寄存器和內(nèi)存。所以說,匯編可以用一句話概括:匯編就是在寄存器和寄存器或寄存器和內(nèi)存之間來回移動數(shù)據(jù)。就是指數(shù)據(jù)在內(nèi)存和寄存器間來回流動,流動的多了,代表程序很復雜,比如office 等一些大型軟件。
mov eax,0x401000//給 eax 初始化MOV 也可以改成 ADD(加),SUB(減),XOR(異或),OR(或),AND(與)。
后面的操作數(shù)為源操作數(shù),前面的操作數(shù)為目標操作數(shù),最開始是操作碼。其實 ADD……這些也是移動指令:把源加上目標然后移動到目標操作數(shù)里面去。前面表示操作方式,后面表示寄存器和寄存器或寄存器和內(nèi)存,但是只能出現(xiàn)一個內(nèi)存。
比如:ds:[]里面寫個數(shù),表示內(nèi)存單元。ptr 指的是指針 point。word 是兩個字節(jié),還有 byte 是一個字節(jié),dword 是四個字節(jié)。
寫法:byte/word/dword ptr ds:[32 位的數(shù)]。
其實[]里面不但可以寫具體的一個數(shù),還可以寫某一個寄存器的值。方括號的通用格式:reg+reg數(shù)+立即數(shù),只要這個值算出來指向哪一個內(nèi)存單元,
就是那個內(nèi)存單元(現(xiàn)在先記住,不要管為什么,后面會講)。
第一個寄存器叫做 BASE 寄存器(8 個寄存器都可以),第二個寄存器是 INDEX 也是 8個寄存器之一,后面乘一個數(shù) scale(1,2,4 或 8,也就是 2 的 0 次方,2 的 1 次方,2的 2 次方,2 的 3 次方),后面再加一個數(shù)(DISP)。
BASE+INDEX(1,2,4,8)+DISP 可以是有以下五種組合
BASE
INDEX*(1,2,4,8)
DISP
BASE+INDEX×(1,2,4,8)
BASE+INDEX×(1,2,4,8)+DISP
每一種組合都可以。
我們只有把最簡單的東西用熟了,才能熟能生巧。
練習:
mov eax,ds:[0x401000+8*eax+eax];這個可以執(zhí)行嗎?
cpu 實現(xiàn)了將地址賦給寄存器:LEA 指令把方括號里面內(nèi)存的編號給目標寄存器:load
effective address。
當一個值不好確定寬度時,使用 dword ptr 或者 word ptr,byte ptr,源可以是內(nèi)存或寄存器,也可以是立即數(shù),但是目標不能是立即數(shù)。兩方都可以是內(nèi)存,但是內(nèi)存只能在一個地方出現(xiàn)。兩邊的數(shù)據(jù)寬度要一樣。所以指令是由操作碼和操作數(shù)組成,操作碼是表明我想干什么。復雜的指令也是由簡單的指令組合而成。
課后理解:
內(nèi)存同樣由許多寄存器組成,但是此寄存器非彼寄存器,速度不及通用寄存器的幾十分
之一,寬度為 8 位。見圖 2-3:
如圖 2-3,為了區(qū)別內(nèi)存和 cpu 內(nèi)部的寄存器,我們將內(nèi)存中的寄存器打上“[]”,專業(yè)術(shù)語稱之為“地址”。圖中的內(nèi)存大小從 0 到 0xFFFFffff,也就是說有 0xFFFFffff 個內(nèi)存寄存器存在,內(nèi)存地址從 0-0xFFFFffff。
注:此處 0xFFFFffff 寫法為何不寫成 oxFFFFFFFF?
十六進制不區(qū)分大小寫,這樣寫是為了便于識別,我們可以很清楚的看出有 8 個 F。
內(nèi)存地址的用處是什么?
當用戶運行程序時,cpu 需要不停地去從存儲區(qū)取代碼和數(shù)據(jù),這樣非常耗時,于是cpu 先將可能用到的代碼和數(shù)據(jù)從存儲區(qū)全部放入內(nèi)存,再從內(nèi)存中取數(shù)據(jù)和代碼。看似多了一個過程,但是從內(nèi)存中獲取比存儲區(qū)快得多,所以節(jié)省了很多時間。
我們?nèi)绾问褂脙?nèi)存地址呢?我們通過實例來了解。
將 32 位數(shù) 0x12345678 存入內(nèi)存中的 0x12FFB8 地址處:
說明:我們從圖 2-4 可以看出:數(shù)值的高位存儲在內(nèi)存地址中的高位。
內(nèi)存地址的表示方法有哪些?
內(nèi)存地址的表示方法有很多,除了上圖中的表示方法外,還有其他四種表示方法。
以下是內(nèi)存地址表示方法的組成成員:
·位移(Displacement) - 8 位、16 位或 32 位值
·基(Base) - 通用目的寄存器
·索引(Index) - 除 ESP 外的通用目的寄存器
·比例因子(Scale Factor) - 1,2,4 或 8
下列五種地址模式為常用組合(圖 2-3):
·位移
·基
·基 + 位移
·(索引×比例因子)+ 位移
·基 + (索引×比例因子)+ 位移
為什么只有五種表示方法,而且比例因子還有限制?
極有可能的原因是(猜測):計算機只識別機器語言,所以我們要將內(nèi)存地址的表示方法翻譯成機器語言才能得到執(zhí)行。組合越多,翻譯起來越麻煩,cpu 的技術(shù)員們只好訂個規(guī)矩:只能使用五種表示方法,否則一律不識別。
練習:
用實例表示以上五種組合方式。
1.[0x234791]//vc6 不支持
2.[reg]
3.[reg+0x10234]
4.[reg+reg*{1,2,4,8}]
5.[reg+reg*{1,2,4,8}+0x1234]
注:reg 表示通用寄存器。
課后疑問:
回答:不可以
回答:如果結(jié)果超過 32 位溢出,則計算機只取 32 位。
課后總結(jié):
內(nèi)存的通用格式:reg+reg*數(shù)+立即數(shù)
課后練習:
練習復雜地址表達形式的操作如: lea [eax +eax*0x02+0x12548],eax
2.3 匯編指令
本節(jié)主要內(nèi)容:
老唐語錄:
復合指令:
lea esp,[esp-4]
mov [esp],eax
使用 vc6 調(diào)試觀察內(nèi)存的變化:
這兩條指令的組合就是我們學的新指令:push eax。
mov eax,[esp]
lea esp,[esp+4]就是指令 pop eax。
練習:
將 eax 替換成其他 7 個寄存器并測試
總結(jié):
pop ERX 也可以理解為:
lea esp,[esp+4]
mov ERX,[esp-4]
所以 pop esp 可以簡化為
lea esp,[esp+4]
mov esp,[esp-4]
練習:
在 VC6 中單步過程時,可以在代碼窗口右鍵 go to disassmbly,一步一步運行,并觀察 eip 變化。
其實 eip 一直在變化。在 80x86CPU 中,eip 寄存器指向的是將要執(zhí)行代碼的位置,
代碼本身也是數(shù)據(jù),也是由二進制構(gòu)成。
Intel 指令的長度不同,最短的只占一個字節(jié),最長 15 個字節(jié)。
比如:
xchg eax,eax
mov eax,0x1234567
通過 VC6 中的匯編窗口,右鍵 code bytes,可以看見指令的二進制內(nèi)容。
xchg eax,eax 又稱為 nop。
數(shù)據(jù)包含代碼,代碼只是數(shù)據(jù)的一部分,eip 指向的位置才稱為代碼。
前面提到計算機和數(shù)學(算盤)的不同點是計算機是定寬的。
第二個不同點是數(shù)學中的算盤只負責存儲數(shù)據(jù),并是由人操作的,而計算機相當于有兩個算盤,其中一個存儲數(shù)據(jù),另一個負責操作算盤。操作和運算本身也是代碼,并存在于內(nèi)存中。但是代碼本身不能存放在寄存器,只能放在內(nèi)存中,只有數(shù)據(jù)可以放在寄存器中。但是專門有一個寄存器負責指向執(zhí)行代碼(操作算盤的人在哪里,在內(nèi)存中的哪個位置)。eip 是寄存器,所以他的值可以被改變。計算機取名字是有規(guī)則的,以字母、數(shù)字或下劃線組成,并且不以數(shù)字開始。
mov eax,offset 標號名(標簽);用名字的時候要加個 offset,其實就是立即數(shù)
每個地方都可以取個標簽,如:
lab: mov eax,ecx
mov ecx,offset lab
既然匯編指令就是在寄存器和內(nèi)存間移動指令,那么我們可以使用 mov 來修改 eip:
mov eip,寄存器/立即數(shù)
簡寫為 (取別名):
jmp 寄存器/立即數(shù)
此外,
push offset lab
mov eip,eax
lab :…
稱為 call eax
ret 就是
lea esp,[esp+4]
mov eip,[esp-4]//jmp [esp-4]
的簡寫形式。
ret 后面可以加一個數(shù) 0x04,0x08……這個數(shù)是兩個字節(jié)的寬度:
ret IW,比如 ret 0x4
課后理解:
總結(jié)
- 上一篇: 可以学计算机知识的手游,玩手游还能学知识
- 下一篇: 游戏运营必须知道的知识(二),入行必备!