再研究计算机汇编语言为单片机打下坚实的基础一

【滴水基础】1.汇编语言(上)
一:进制

1进制的定义:由1个符号组成(不一定为数字1,可以是其它字符a\b\c等),逢1进1

0=0;1=1;2=11;3=111;4=1111

2进制的定义:由2个符号组成(不一定为数字0、1,可以是其它字符a\b\c等),逢2进1

0=0;1=1;2=10;3=11;4=100;5=101;6=110;7=111;8=1000;

3进制的定义:由3个符号组成(不一定为数字0、1、2,可以是其它字符a\b\c\d等),逢3进1

0=0;1=1;2=2;3=10;4=11;5=12;6=20;7=21;8=22;9=100;10=101;11=102;12=110;13=111;14=112;15=120;16=121;17=122;18=200;19=201;20=202

7进制的定义:由7个符号组成(不一定为数字0、1、2、3、4、5、6,可以是其它字符a\b\c\d等),逢7进1

0,1,2,3,4,5,6,

10,11,12,13,14,15,16(13)

20,21,22,23,24,25,26(20)

问题:1+1=3对吗?

答:进制定义不同,如果十进制定义为:0,1,3;则1+1=3

应用:进制的加密解密

二:进制运算

进制本质:查数(每一个进制都有自己独立的体系)

八进制的运算:

0,1,2,3,4,5,6,7

10,11,12,13,14,15,16,17(15)

20,21,22,23,24,25,26,27(23)

2+3=5:从2向后查3个数

2*3=6:2个3或者3个2,在3后面再查3个数

4+5=11:从4往后再查5个数

4*5=24:4个5或者5个4

总结:

(1)  进制的本质是查数

(2)  十进制运算轻松的原因:十进制加减乘除表

八进制的加法表:

1+1=2

1+2=3  2+2=4

1+3=4  2+3=5  3+3=6

1+4=5  2+4=6  3+4=7  4+4=10

1+5=6  2+5=7  3+5=10 4+5=11 5+5=12

1+6=7  2+6=10 3+6=11 4+6=12 5+6=13 6+6=14

1+7=10 2+7=11 3+7=12 4+7=13 5+7=14 6+7=15 7+7=16

八进制乘法表:

1*1=1

1*2=2  2*2=4

1*3=3  2*3=6  3*3=11

1*4=4  2*4=10 3*4=14 4*4=20

1*5=5  2*5=12 3*5=17 4*5=24 5*5=31

1*6=6  2*6=14 3*6=22 4*6=30 5*6=36 6*6=44

1*7=7  2*7=16 3*7=25 4*7=34 5*7=43 6*7=52 7*7=61

277+333=?

7向后移动3位为12,故进1个bit位;第二个bit位同样12+1为13,向前进1个bit位;2+3+1=6,故277+133=632

236-54=?

6向前移动4位为2,13向前移动5位为6,2向前移动1位为1,故236-54=162

276*54=?

4个6=十进制的24/八进制的30;4个7=十进制28/八进制34;4个2=10;根据bit位添加0,则 30+340+1000=1370(这里是八进制相加);

同理,5个6=36;5个7=43;5个2=12,根据bit位置添加0,则36+430+1200=466+1200=1666;

同理,根据bit位置添加0,16660+1370=?,6+7=15,3+6=11,1+6=7,再次根据bit位置添加0:

即150+1100+7000+10000=1250+7000+10000=10250+10000=20250

234/4=?

230/4=40余34(先23转化为十进制19除以4为4余3);34(转换十进制24+4=28)/4=7,则234/4=40+7=47

问题:计算机为什么要使用2进制:

计算机信号在物理层的传输是通过电信号,而电信号受到硬件的制约,只有正负极。

二进制的书写:

0000,0001,0010,0011,0100,0101,0110,0111

1000,1001,1010,1011,1100,1101,1110,1111

十六进制:

0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

为什么要使用十六进制:

一个十六进制,相当于4比特的2进制,可以更好的显示汇编

三:数据宽度

数据宽度定义:在计算机中,由于硬件制约,超过最长宽度的数据会被丢弃。

计算机常用的数据宽度:

(1)  位(比特):bit    大小:1 bit    十六进制表示:0-1

(2)  字节:byte   大小:8bit     十六进制表示:0-FF

(3)  字:word     大小:16bit    十六进制表示:0-FFFF

(4)  双字:doubleword   大小:32bit  十六进制表示:0-FFFFFFFF

四:有符号数、无符号数

背景:不同格式的文件,如exe、txt等都会转化为2进制进行存储,那么如何从计算机中存储的二进制数据中,区分出原始文件的不同格式?

(1)  无符号数编码规则:和传统的十六进制一样

(2)  有符号数编码规则:

例如:对于十六进制进行解析:0x1A 000 000

无、有符号解析(最高位为0,无符号和有符号解析相同):

00001 1010 0000 0000 0000 0000 0000 0000

如果是负数0x9A:

无符号解析:1001 1010(最高位1,十进制:16*9+10=154)

有符号解析:1001 1010(最高位1为负数,十进制:-(2^4+2^3+2^1)=-26)

有符号数的取值范围:

五:原码、反码、补码

有符号数编码规则:

(1)  原码:最高位为符号位,其余数值为本身的绝对值

(2)  反码:

(3)  补码:

例如(以字节为单位):

6=》0000 0110;原码=反码=补码

-1=》原码:1000 0001

反码:1111 1110   补码:1111 1111

计算机对于数据的存储方式:

例如(十六进制表示):

char x=1,在内存中存储为01

char x=-1,在内存中存储为FF

假设数据宽度为1byte=8bit(现实一般为32位,即1dword):

无符号数:0,1,2……FF(十进制:[0,255])

有符号数:

正数:0……7F

负数:FF……80

计算机的取值宽度(1byte):

计算机的取值宽度(1dword):

总结:

(1)  了解计算机如何存储整数,那么浮点数、字母、汉字是如何存储?

答:C语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit, double数据占用64bit。无论是单精度还是双精度在存储中都分为三个部分:

符号位(Sign) : 0代表正,1代表为负

指数位(Exponent): 用于存储科学计数法中的指数数据,并且采用移位存储

尾数部分(Mantissa):尾数部分

其中,float存储方式:

double存储方式:

1:计算机如何存储英文字符:

ASCLL:对英文字母和符号进行了编码,总计28个

LATIN-1:兼容ASCLL,同时对欧洲符号进行编码,总共有256个

2:计算机如何存储中文字符:

GB2312:兼容ASCLL,对常用6000多汉字进行了编码

GBK:对两万多汉字进行了编码,兼容GB2312

BIG5:兼容ASCLL,台湾繁体字编码

3:Unicode:对世界上主流国家常用的语言进行了编码,兼容ASCLL,不兼容GB2312,GBK。。。。

具体存储方案:UTF-8     UTF-16   UTF-32

(2)  计算机只认识二进制,如何进行加减乘除的运算

答:通过位运算来计算

六:计算机不会做加法

为什么要学习位运算:1.有些功能需要通过位运算,如调试器等2.高等的四则运算

(1)与运算(and):两个位都为1时,结果才为1

—在电路图中表现为串联电路

(2)或运算(or):只要1个1就为1

—在电路图中用并联表示

(3)异或运算(xor):不一样的时候为1

—在电路图中表现为交叉电路图

(4)非运算(not):0就是1,1就是0,是单目运算(只需要1个数就可以运算)。

—1101 1000

—not(~) 0010 0111

(5)左移(<<):各二进制位全部左移若干位,高位丢弃,低位补0

—shl(<<) 1101 1000

—左移2位:0110 0000

(6)右移(>>):各二进制位全部右移若干位,低位丢弃,高位补0或者补符号位1

—shl(>>) 1101 1000

—右移2位:0011 0110

—int:整形,宽度为32bit

—unsigned:无符号数

—%d\n:输入输出的格式字符串,这里表示以10进制表示,\n为换行

—a>>2:整型变量a向右移动2个bit

—int:默认为有符号数

—最高位为1,则补1(注意:2个bit都补1)

总结:计算机只能做位运算,即加减乘除都无法直接计算

七:位运算之加减乘除

4+5=?的运算过程

—总结:在不考虑进位的情况下,异或的结果等于相加的结果

—例如:下面极端情况相等

—step1:异或

—step2:判断是否存在进位(判断是否都为1,都为1才有进位)

—通过与运算(and)来判断

—step3:将异或运算的结果和与运算的结果(左移1bit),再次异或

—step4:再次判断是否存在进位(通过与运算判断)

—这里还是判断step1和step2(左移1bit)的值

—这里全为0,故不存在进位

—总结:

4-5=?的运算过程

—4-5=4+(-5)

—注意:负数在计算机中以补码的形式存储

—(-5)原码:1000 0101;反码:1111 1010;补码1111 1011

—step1:异或

— step2:与运算(不存在进位)

—迭代结束

—4-5=4+(-5)=FF=-1

总结:

(1)  乘法运算本质:X*Y=Y个X相加

(2)  除法运算本质:X/Y=X能减去多少个Y

(3)  任何复杂运算本质=四则运算=加减法=位运算

八:汇编学习环境的搭建

学习汇编的目的:

—开发:了解c语言和汇编的关系

—安全:了解汇编和二进制的关系(前者也需要了解)

DTDebug下载:https://www.bcdaren.com/download

DTDebug界面:

—如果F8失效,加上Fn一起按即可

—要以管理员打开,然后需要配置路径才不会报错

—随意打开一个exe文件,pause表示程序暂停

进来后可以稍微拖动拖动界面,变成自己喜欢的分布,大致分为四个区域:

1、左上为反汇编代码区

2、右上角为寄存器区

3、左下角为内存区

4、右下角为堆栈区

—写入代码,按F8单步步过

—寄存器内容改变

—EIP指向反汇编窗口中,cpu即将执行的程序地址

九:通用寄存器

计算机存储数据(读取速度逐渐下降):cpu > 内存 > 硬盘

—根据cpu的类型不同,提供不同的数据存储

—32位cpu:8bit/16bit/32bit

—64位cpu(2005之后都是64位cpu):8bit/16bit/32bit/64bit

32位通用目的寄存器的指定用途如下:

—不能超过32位,超过部分会被丢弃

EAX:累加器(Accumulator),一般存储调用函数的结果

ECX:计数器(Counter),REP重复执行的时候判断执行次数

EDX:I/O指针,数据寄存器(data)

EBX:DS段的数据指针,基址寄存器(base)

ESP:栈顶指针寄存器(Stack pointer)

EBP:栈底指针寄存器(base pointer)

ESI:字符串操作的源地址(Source index)指针

EDI:字符串操作的目标地址(Destination index)指针

汇编的本质:通过指令,让数据在寄存器/内存/堆栈中来回流动

MOV指令:

—立即数到寄存器:

—向EAX存入1:mov eax,1

—向ECX存入1:mov ecx,1

—寄存器到寄存器

—将eax的内容存入edx:mov edx,eax

eax可以分成4个部分:eax共0~31(32位), ecx,edx,ebx寄存器类似

—其中0~7位叫作AL,low表示低位

—8~15位叫作AH,high表示高位

—整个0~15位又称为AX

—32位的寄存器有8个,分别是:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI,每个寄存器都有一个编号,分别是:0号,1号,2号,3号等。

—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。这两个寄存器使用相对较少。

通用寄存器即 cpu 常用的寄存器,主要实现逻辑和算术运算、地址计算和内存指针。

—注意:只有EAX,ECX,EDX,EBX存在八位寄存器

—注意:反汇编界面是十六进制

—可以明显看到高位、低位的变化

—寄存器之间的数据传输,数据的位数必须一样

—如,8位寄存器只能和8位寄存器之间传输,这里8位寄存器赋值16位寄存器就会报错

—应该改为:mov bx,cx

作者:沙漠里的鲸 https://www.bilibili.com/read/cv19200539/ 出处:bilibili

发表评论

邮箱地址不会被公开。