Art of Assembly
Съкратен и много неточнен превод на част от 1 глава от книгата Art of Assembly
За да се започне изучаването на асемблер, човек трябва да е наясно с няколко неща
1. двойчна и шестнадесетична бройна система
2. булева алгебра и логика
3. пакетиране на информация
4. други
Много хора, след като видят двойчната (bin) и шестнадесетичната (hex) бройна система намират, че това е сложно и е безмислено да се занимават с битове и байтове след като има езици като Perl, Python, PHP и др., в който може би никога няма да ви се наложи да ги използвате. Но ако сте решили да се занимавате с асемблер това е основна предпоставка за да може да го научите. Така че, да започваме.
Бройни системи
В тази глава се описват няколко важни концепции като двойчна и шестнадесетична бройна система, организацията на битово ниво (bits, nibbles, bytes, words, double words), положителни и отрицателни числа, аритметични, логически, преместващи (shift) и редуващи (rotate) операции, пакетирането на информацията и ASCII символа таблица. Съвременните компютри не работят с десетичната бройна система (с която сме свикнали), а използват bin и hex системите. Това е основен материал и е задължително да разберете същината на изложеното тук.
Обясненото тук ще Ви послужи, ако някога искате да програмирате на C, C++ и др. и ако искате да разберете защо базите данни имат различни типове полета и други интересни въпроси на който може да си отговорите ако прочетете всичко по-долу.
Нормалните числа (десетичната бройна система (dec))
Числото 123 представлява:
1*10^2 + 2*10^1 + 3*10^0
което е 100+20+3 = 123
Числото 123.45 представлява:
1*10^2 + 2*10^1 + 3*10^0 + 4*10^(-1) +5^(-2)
Двойчни числа
Съвременните компютри работят като използват бинарна логика (true и false). Компютрите представят стойностите като използват две нива на тока 0v и 5v (обикновенно). С тези две различни нива ние може да представяме две различни неща, който кореспондират с 0 и 1 в бинарната бройна система. Системата е точно като десетичната с 2 разлики - има само две числа 0 и 1, и използва за основа на степента 2 вместо 10.
Много е лесно да се представи bin в dex - 10101110 е:
1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 |
1*2^7 + | 0*2^6 + | 1*2^5 + | 0*2^4 + | 1*2^3 + | 1*2^2 + | 1*2^1 + | 0*2^0 |
| | | | | | | |
Степента отговаря на позициията на бита. Брой се от ляво на дясно 0, 1 .. 6,7
Малко по-сложно е представянето на dex в bin - 135 e:
2^7 е 128, 128 е най-близкото число по-малко от 135, което може да се представи като степен на 2. 135-128=7, записваме 1
1
2^6 е 64, 64>7, записваме 0
10
2^5 е 32, 32>7, записваме 0
100
2^4 е 16, 16>7, записваме 0
1000
2^3 е 8, 8>7, записваме 0
10000
2^2 е 4, 7-4=3, записваме 1
100001
2^1 е 2, 3-2=1, записваме 1
1000011
2^0 е 1, 1-1=0, записваме 1
10000111
Следователно числото 135 в двойчен вид ще е 10000111
Двойчен формат
Всяко двойчно число може да съдържа неопределено голям брой 0 и 1.
111 000111 00000000111,
са едно и също, ако започва с 0 едно bin число тя може да се махне без това да повлияе на стойноста на числото.
11111111 - един байт се състои от 8 бита
За по-удобно и пригледно 1 байт ще го записваме с интервал посредата, който разделя байта на две части наречени старши и младши битове.
1111 1111
Дясната страна на един байт се състой от старши битове, а лявата от младши битове.
Всяка позиция на битовете в байта си има номер. Започва да се брой от дясно наляво, от 0 до ..
x7 x6 x5 x4 x3 x2 x1 x0
Ако е шестнадесет битово записване то номерата на битовете ще са:
x15 x14 x13 x12 x11 x10 x9 x8 x7 x6 x5 x4 x3 x2 x1 x0
С един байт могат да се представят 2^8=256 числа. Като те се в границата от -128 до +127, ако се използват числа със знак.
Шестнадесетични числа
Използват се защото е много по-кратко от двойчните. Използват се числата от 0 до 9 и A,B,C,D,E,F за изразяване на шестнадесетичните числа.
Чрез едно шестнадесетично число може да се представят 4 бита. Един байт в шестнадесетично число се състой от две цифри (или букви).
Шестнадесетичното число 14АF е числото:
1*16^3 + 4*16^2 + 10*16^1 + 15*16^0
dec Binary Hexadecimal
1 0000 0
2 0001 1
3 0010 2
4 0011 3
5 0100 4
6 0101 5
7 0110 6
8 0111 7
9 1000 8
10 1001 9
11 1010 A
12 1011 B
13 1100 C
14 1101 D
15 1110 E
16 1111 F
Ако трябва да превърнем едно шестнадесетично в двойчно число това е доста лесно:
1 4 A F
0001 0100 1010 1111
Ако трябва да се направи обратното на двойчното число му се прибавят нули отпред за да стане делимо на 4 бита, например имаме 10110.
Което е 0001 0110
0001 0110
1 6
Аритметични и логически оператори за работа с двойчна и шестнадесетична бройна система
Всичките операции - събиране, умножение, деление ... трябва да може да ги правите върху bin, hex за да може да продължите напред. Най-лесно става с използване на елка, която позволява тези операции. Ако сте на OS Win може да използвате елката (научен формат(това е за майка ми, която иска всичко подробно и да си запише по възможност)).
Операции като:
AH + 1F или AA03*DE12, стават много по-лесно с еклата (както може да се досетите (предполагам)).
Логически са операторите AND, OR, XOR, NOT, които са обяснени по-долу.
AND
0 и 0 = 0
1 и 0 = 0
0 и 1 = 0
1 и 1 = 1
OR
0 и 0 = 0
1 и 0 = 1
0 и 1 = 1
1 и 1 = 1
XOR
0 и 0 = 0
1 и 0 = 1
0 и 1 = 1
1 и 1 = 0
NOT
NOT 0 = 1
NOT 1 = 0
Както виждате това е в основата на всички програмни езици.Например в Perl
print "yes" if ($a and $b);
за да премине теста то и двата скалара трябва да имат стойност различна от undef или 0, казано по друг начи нула
По долу са показани няколко примера за използването на логическите оператори върху bin числа. Пример с OR
1101 1010
0010 1110
---------
1111 1110
Пример с AND
1101 1010
0010 1110
---------
0000 1010
Положителни и отрицателни числа
С bin могат да се представят числата от -128 .. -1 0 .. 127.
За да се представи едно число дали е положително или отрицателно се използва следния принцип.
Старшият бит показва знака, ако той е 0, то числото е положително, ако е 1 е отрицателно.
Например:
0111 1101 - положително
0001 0010 - положително
1010 0001 - отрицателно
FFFF - отрицателно
0FFFF - отрицателно
FFF - положително
100 - положително
D10 - положително
D100 - отрицателно
Има два етапа за конвертиране на положителни в отрицателни при двойчното записване.
1. Обърнете всички битове на числото - използвайте NOT върху него
2. Прибавете едно към така получениете битове.
Имаме числото 21
00010101
1. 11101010
2. 11101011 е -21
Ако искаме да обърнем отрицателно в положително, преминаваме през абсолютно същият алгоритъм.
7FFF
7 F F F
0111 1111 1111 1111
1000 0000 0000 0000
1000 0000 0000 0001
8 0 0 0
1000 0000 0000 0000 -32,768
0111 1111 1111 1111
1000 0000 0000 0000
(Това е един доста странен пример, който след като схванете нещата се замислете за него (може ли да се представи най-малкото отрицателно число в положително).
При 16-битовите, ако започва с FF e отирцатено, ако е с 00 то е положително.
shift, rotate
left shift
101 - 5
1010 - 10
Като се измества всичките битове с едно на ляво все едно се умножава числото с 2 при бинарните числа. При десетичната бройна система е аналогично, като се преместят всички числа с едно наляво все едно умножаваме с 10. Обобщено правилото е, че преместването с 1 на всички числа наляво е все едно числото да бъде умножено с това към коя бройна система е. При bin с 2, при hex с 16, dec с 10 и т.н.
right shift
Изместват се надясно с един бит - делене на 2 при bin. Но това не е съвсем вярно, защото има разлика м/у положителни и отрицателни числа.
Ако искаме да се запази знака то трябва да преместим всички битове с едно надясно, но в седмия бит да си оставим стойността която е била преди преместването (aritmetic shift right)
left, right rotation
същото като shift, но последната стойност става първа или стойността в бит 7 става стойност на бит 0, бит 0 в бит 1 и т.н.
ASCII Character Set
Разделен е на 4 части, първата от 0 до 31 се състой от не принтируеми знакове, който се наричат контролни (управляващи).
Следващата група от 32 символа се състой от знакове, специални знакове и числата
Следващата група от 32 символа се състой от A .. Z, и 6 специални символа
Последната група от 32 символа се състой от a .. z, и 5 специални символа и един контролен (delete)
Разликата между голямата и малка буква S (а и между всички останали) е в бит 5, ако той е 0 то буквата е голяма, ако е 1 то буквата е малка. Ако бит 6 е 0 то символа е конторолен ако бит 5 е 0, а ако бит 5 е 1 то символа е специален
Булева алгебра
Логическите кръгове са в основата на програмитането и компютрите. За да ги разберете, трябва да знаете числената логика и булевата алгебра. Всеки логически кръг може да се представи с помоща на булевата алгебра. Материала по-долу е предназначен за тези който смятат да се занимават с програмиране на хардуер или софтуер управляващ хардуер.
Булева алгебра (БА)
Булевата алгебра е дедуктивна математическа система основана на 0 и 1. Бинарният оператор " ° " приема две булеви числа и връща едно. Всяка математика си има постулати. По-долу са изброени тези, които засягат БА.
"°" е асоциативен ако (А°B)°C=А°(B°C)
Единствените числа разрешени в БА са 1 и 0, често наричани истина и лъжа. Символа * е логическото AND. + е логическото OR. ' е NOT.
AB e A * B или A AND B
A+B e A OR B
A' e NOT A
БА използва само AND, OR и NOT
Еднаквите елементи по отношение на ° са 1 и + са 0.
За всяка стойност A има A'.
+ и ° са асоциативни. (А + В) + С = А + (В + С)
Ето и теоремите на БА:
Теорема 1: A + A = A
Теорема 2: A • A = A
Теорема 3: A + 0 = A
Теорема 4: A • 1 = A
Теорема 5: A • 0 = 0
Теорема 6: A + 1 = 1
Теорема 7: (A + B)’ = A’ • B’
Теорема 8: (A • B)’ = A’ + B’
Теорема 9: A + A•B = A
Теорема 10: A •(A + B) = A
Теорема 11: A + A’B = A+B
Теорема 12: A’ • (A + B’) = A’B’
Теорема 13: AB + AB’ = A
Теорема 14: (A’+B’) • (A’ + B) = A’
Теорема 15: A + A’ = 1
Теорема 16: A • A’ = 0
Булеви функции
F=(A°B) + C
A=1
B=1
C=1
F= (1 AND 1) OR 1
F= 1 OR 1
F=1