当前位置:
首页 > temp > 简明python教程 >
-
汇编语言1:基础知识
这个假期开始系统学习汇编语言,采用跟随视频教程的方式,所用教程是网易云课堂中的《汇编语言从0开始》,讲者是workWork。该课程一共有167个课时,每个课时从几分钟到十几分钟不等,时间不长,短小精悍,反馈及时,让人有动力一直看下去。这门课程很适合零基础的同学,因为在正式编程前,讲者用了大量时间讲述基础性的知识,包括二进制十进制十六进制、CPU执行指令的过程、寄存器的讲解、栈的使用等等。我个人认为,即使你已经不算零基础了,认真地看完这些课程,巩固一下基础知识也是必要的。我之前看过一本基于Linux的教材,因为Linux采用的是AT&T风格,与DOS/Windows的Intel风格有很大差异,所以即使也写过几个汇编小程序,但始终觉得对于寄存器、指令/数据长度以及栈的概念懵懵懂懂,基础并没有打好。我建议大家如果是初学者,还是先从DOS/Windows平台的汇编开始学习比较好,尤其是要使用Windows XP中的debug程序反复练习,这样可以在编程之前打好坚实的基础。
下面对编程之前的基础知识做一个小小的总结。
一、十进制、二进制和十六进制
二进制之所以重要,是因为整个计算机体系就是建立在二进制的基础上的,实际上所有的指令和数据在计算机中存储和运算的形式就是二进制。十六进制之所以重要,是因为查看内存中的指令和数据时,是以十六进制显示的。一个十六进制数字,实际上相当于四个二进制数字的表示。这方面需要掌握以下几个知识点:
- 十进制与二进制的相互转换/快速转换
- 十进制与十六进制的的相互转换/快速转换
- 十六进制与二进制的相互转换/快速转换
基础的相互转换就不说了,即使对于初学者也应该是容易掌握的。说一下快速转换的方法。
-
十进制快速转换成二进制
首先对于二进制来说,位于最末一位的1表示加1,右数第二位表示加2,依次类推为4、8、16、32、64。对于100以内的十进制数,只能是由以上几个数字相加得成。那么我们就可以开始凑了。比如98,可以写成64+32+2,再把对应位置为1,即1100010。
-
十进制快速转换成十六进制
这个方法只能用在小于256的数。很简单,先用该数除以16,得到一个结果和一个余数。比如81=5*16+1,则十六进制表示为51H。
-
十六进制和二进制的快速转换
上文说过一个十六进制数字可以由四个二进制数来表示,比如7EH,就是把7用二进制表示,E用二进制表示,即0111 1110。反之亦然,二进制转换成十六进制时,每四个数字划分即可。
最后,记住一个式子:
字节byte = 2个十六进制数字 = 8个二进制数字 = 8比特bit
二、CPU、寄存器和指令执行
-
地址信息、数据信息和控制信息
6个小题,掌握了就可以了。
(1)1个CPU的寻址能力为8KB,那么它的地址总线宽度为 13
8KB = 8*1024字节,总共是2的13次方
(2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023
(3)1KB的存储单元可以存储 1024*8 bit,1024 Byte
(4)1GB, 1MB, 1KB 分别是 2^30 2^20 2^10 Byte
(5)地址线有16根,寻址能力为64KB,20根,1MB,24根,16MB,32根,4GB
(6)数据线有8根,一次可以传送数据为1Byte,16根,2Byte,32根,4Byte
-
寄存器
(1)通用寄存器
ax = ah + al
bx = bh + bl
cx = ch + cl
dx = dh + dl
一般用来存放数据,对于ax来说,能表示最大值为FFFFH,即0-66535。ax是16位,AH是8位,ah最大可表示FFH,即0-255。对于ax存放的数据是一个字,即两个字节。而一个地址当中只能存放一个字节,即1个字需要2个地址连续的内存单元存放,高位地址存放高位字节,低位地址存放低位字节
(2)用于表示地址的寄存器
段地址:偏移地址
ds si
es di
ss bp
cs ip
sp
bx
物理地址 = 基础地址 + 偏移地址
基础地址 = 段地址 * 16(10H)
其中cs:ip表示读取指令的地址,ds 是段寄存器,一般以ds:[0]的形式表示要使用的数据所在的地址。
-
指令执行
读取指令的地址为cs:ip。
(1)指令执行的过程:
①CPU从cs:ip所组成的地址中读取指令,将这个指令存放在指令缓存器中;
②ip = ip + 所读指令的字节数;
③执行指令缓存器中的内容,回到步骤1,重复这个过程。
(2)指令执行要完成的任务:
①数据在什么位置?
②处理数据;
③把处理过后的结果储存起来。
三、debug指令
r 显示寄存器内容
d 显示内存中的内容
段地址:偏移地址 - 偏移地址
u 将内存中内容翻译成汇编指令
a 向当前内存中写指令(汇编指令)
e 加上段地址:偏移地址,即向当前内存中写入内容(16进制)
四、栈
栈就是一段连续的内存空间,遵循后进先出的准则。栈的操作有两个,分别是入栈和出栈。栈的地址由ss:sp表示。入栈指令是push加地址,出栈指令是pop加地址。注意push和pop指令后加的地址是待入栈数据的地址/出栈后数据存放的地址。ss:sp永远指向栈顶数据,可以由程序员修改决定。注意使用栈时一定要防止越界。
push -> SP - 2 -> SS:SP 字型数据存入
pop -> SS:SP字型数据取出 -> SP - 2
五、基本的汇编指令
-
移动指令
mov 寄存器,数据
mov 寄存器,寄存器
mov 寄存器,内存单元
mov 内存单元,寄存器
mov 段寄存器,寄存器
mov 寄存器,段寄存器
-
运算指令
add 寄存器,数据
add 寄存器,寄存器
add 寄存器,内存单元
add 内存单元,寄存器
sub
-
转移指令
转移指令能够修改ip或cs,例如jump 2000:0,实际上就是把cs改成2000,ip改成0,那么下一条指令就是从2000:0开始执行。
六、编程前的总结
-
关于寄存器与地址表示
CS:IP 和指令有关
DS:[0] [1] … 和数据有关
SS:SP 临时性数据(栈)
-
关于指令执行的过程
通过汇编指令修改CPU中寄存器中的内容。需要考虑的问题有:
(1)数据在哪里?
(2)数据的长度:字节型数据 字型数据 AX BX CX DX AH AL BH BL
(3)数据的处理 ADD SUB
(4)数据存放到哪里?
-
关于程序员的工作
数据是我们程序自己安排,存放在哪里也要自己安排,指令在哪里也要自己安排——相比高级语言,汇编语言给程序员绝对的自由,然而自由的代价是谨慎,汇编语言比高级语言更容易出现种种问题。
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数