13 个Python开发者必知的Python GUI库
284
2022-08-04
汇编语言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)数据存放到哪里?
关于程序员的工作
数据是我们程序自己安排,存放在哪里也要自己安排,指令在哪里也要自己安排——相比高级语言,汇编语言给程序员绝对的自由,然而自由的代价是谨慎,汇编语言比高级语言更容易出现种种问题。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~