16位汇编语言的学习小结

来源:互联网 发布:淘宝韩国正品女装 编辑:程序博客网 时间:2024/05/22 12:44

前言:前一段时间一直在学习汇编语言,使用的书籍就是最经典的王爽那本书,现在也学习到了一个阶段,想着是不是把学了东西做个小结。


一些不容易弄明白的概念

1. 16位、32位、64位机和三大总线的关系

众所周知,CPU和外部芯片做信息交互必须使用三大总线:地址总线,数据总线,控制总线。
这三大总线相对于CPU来说可以称为外部总线,CPU内部由运算器(处理信息)、控制器(控制)、寄存器(存储信息)等器件构成,这些器件靠内部总线相连。汇编程序员通过改变各种寄存器中的内容来实现对CPU的控制。
再说回外部总线,CPU连接外部芯片的一些管脚和这些总线相连,所以这3种总线的宽度标志了CPU的不同方面的性能。

地址总线宽度为n,CPU 最多可以寻找2n个内存单元;
数据总线宽度为n,一次可传送的二进制数据为n位;
控制总线宽度为n,意味着CPU能提供对外部器件的控制方式有n种。

我们所说的16位、32位、64位结构的CPU,并不是说它的地址总线(寻址能力)是16位,比如说最经典的16位的8086CPU的地址总线实际上是20位的,而是指CPU的寄存器的位宽为16位,CPU的运算器一次最多处理16位数据,他们之间的通路(内部总线)是16位的。而且这里还有另外一种叫法,就是字长16位或者叫16位机。 (ps:这一段是我根据自己查询网上和书上的资料,再结合自己对CPU的理解总结的,如有错误欢迎指正。)

2. X86机,X64机,IA64和32位、64位操作系统的关系

再来说说X86结构(架构)的机器,很多机器都可以被称为X86结构,不仅仅是计算机,还有可能是其他的嵌入式机器。X86结构指的是特定微处理器执行的是intel通用计算机语言指令集(RISC精简指令集。随着Intel的8086CPU诞生了X86架构),它定义了芯片的基本使用规则,所以X86结构的CPU还有可能是64位的,而不是一般以为的32位机,跟操作系统的32位(X86)系统也没有关系。

x86是一个intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合,X与处理器没有任何关系,它是一个对所有*86系统的简单的通配符定义,例如:i386,586,奔腾(pentium)。由于早期intel的CPU编号都是如8086,80286来编号,由于这整个系列的CPU都是指令兼容的,所以都用X86来标识所使用的指令集合。如今的奔腾,P2,P4,赛扬系列都是支持X86指令系统的,所以都属于X86家族。

什么是X86架构的典型特征呢?指令的长度不定、指令数量繁杂、但是指令扩展性较强是我们最直接的印象。X86处理器都拥有一个庞大的译码器,实际上X86内部的计算部分依然是经典的RISC简明架构,再加上存储堆栈等种种因素,X86处理器现在面临核心面积较大,发热较高效率较低等问题,并不适合在手机平板等设备中使用。

与X86架构不同的著名的另一个架构是ARM架构。ARM架构的英文名是Advanced RISC Machine,所以ARM架构可以认为是灵活苗条的精简指令集处理器,它被广泛用于嵌入式设备和移动设备,近几年随着每一代架构和工艺的演变,ARM架构处理器性能倍增,已经接近低端X86架构处理器,同时功耗表现依然优秀。
另外,比较经典的其他架构CPU有AMD的Athlon 64(X86-64结构,简称X64,X86指令集的64位扩展超集,向下兼容),Intel的安腾(IA64架构,不兼容X86指令集)。IA64架构的CPU与x86指令不兼容。如果想要执行x86指令需要硬件虚拟化支持,而且效率不高。优点在于IA-64架构体系将拥有64位内存寻址能力,能够支持更大的内存寻址空间。并且由于架构的改变,性能比起x86-64的64位兼容模式更高更强。IA-64操作系统由于只能在intel安腾系列处理器及AMD部分服务器处理器运行,所以主流市场并不常见。而且,这些IA-64架构处理器也不能够使用x64操作系统,而x86-64处理器则可以自由选择x86或是x64操作系统。

英特尔非常清楚,是X86指令集限制了CPU性能的进一步提高,因此,他们正同惠普共同努力开发下一代指令集架构(Instruction Set Architecture ,ISA): EPIC(Explicitly Parallel Instruction Computing,显性并行指令计算)。对英特尔而言, IA-64(英特尔的64位架构)是下一个10到15年的架构。新的ISA将使英特尔摆脱X86架构的限制,从而设计出超越所有现有RISC CPU和X86 CPU的新型处理器。

另外, 还可以参看:32位嵌入式微处理器(processor)一览

3. 为什么使用十六进制数表示机器码

我们都知道计算机中的数据都是以0和1表示,即计算机是以二进制形式来存放数据的,一位二进制数占用一个比特(bit)的空间,并且计算机的最小存储单元是字节(Byte),一个字节占用8个bit的空间,而十六进制数的一位正好相当于二进制数的四位,所以使用2位十六进制的数就正好可以表示一个B(Byte)的数据,而且十六进制的数据进行手动运算(只要几个数都是十六进制就可以类似于十进制一样运算)也比使用二进制更加简单明了(如果使用十进制进行手动运算是更方便了,但是1位十进制数没办法正好表示4位二进制数这个优势中间的运算就会困难很多),十六进制数表示二进制数比使用八进制更加简短,所以现在的机器指令和数据一般都是使用十六进制表示的。
汇编语言和机器码的十六进制表示方式(数制标准表示,使用简码)都是在数字后面加上H或者h(二进制数用B表示,十进制数用D表示可省略),而在使用高级语言编程比如C语言表示十六进制数的时候是在数字前面加上0x。

另外,在8086cpu汇编源程序中,十六进制数据不能以字母开头,需要在字母前加0
不能直接给段寄存器送入数据(8086cpu不支持),需要通用寄存器中介或者使用内存单元中介;
不支持从内存到内存送入数据,需要通过通用寄存器中介。
将数据直接mov到内存中,必须显式的说明访问内存的大小(字节还是字或者其他)。(数据处理的2个基本问题:处理的数据在什么地方要处理的数据有多长
8086CPU中程序加载时,在装入的内存ds:0段之前有256B(使用十六进制表示为100H)的空间存放着PSP(程序段前缀),说明着程序的一些信息,后面紧接着存放程序运行的机器码,所以程序机器码所在的物理地址为ds+10H:0。

4.待续–


16位汇编的子程序结构

一般情况下,都是使用的call和ret来实现子程序的机制的。但是由于X86架构CPU的寄存器数量有限,子程序和主程序可能必须使用相同的寄存器,比如都有循环的时候都要用到cx寄存器,jcxz有条件跳转的时候也要用到cx,所以会存在寄存器冲突的问题。一般我们使用栈来保存寄存器中的内容,解决寄存器冲突问题,这样就有了下面的子程序标准框架:

    sub:;子程序中使用的寄存器入栈           push reg        ;子程序的主要内容:            ;主程序传递过来的参数出栈(少量参数使用寄存器,连续参数用寄存器传参数首地址,高级语言常用栈传参,涉及到 调用惯例)        ......              ;功能代码块        ........        ;子程序中使用的寄存器出栈        pop reg        ;子程序运行的结果入栈(子程序没有返回的话就不用;也可以使用寄存器存储返回)        ;返回(ret、retf)        ret n

– 注意寄存器入栈和出栈的顺序


一个例子

assume cs:codedata segment    db 'Welcome to masm!',0data endscode segment    start:  mov ax,data            mov ds,ax            mov dh,8            mov dl,3            mov cl,2            mov si,0            call show_str        e:  jmp e            mov ax,4c00h            int 21h    ;---------------------------------------------------------    ;function:  show a zero-terminated string   with specified color and location    ;parameters:    line number:dh;     column number:dl    color:cl        ;               Starting address of the string:  ds:[si]    ;return:    none    ;---------------------------------------------------------    show_str:               ;push reg which will be used in this subprogram            push ax         ;Multiplication will use register AX            ;push ax            ;A char and it's properties            push bx         ;The address of the char in the video memory            push es         ;The segment address of video memory:B800h            push si            ;The function code            ;(bx)=(dh)*160+(dl)*2            mov al,160            mul dh            mov bx,ax            mov al,2            mul dl            add bx,ax            ;mov es,0B800H            mov ax,0B800H            mov es,ax        s:  ;judgment            push cx             mov cl,ds:[si]            mov ch,0            jcxz ok            ;Display            pop cx            mov al,ds:[si]            mov ah,cl            mov es:[bx],ax            inc si            add bx,2            jmp short s            ;pop        ok: pop cx            pop si            pop es            pop bx            pop ax            retcode endsend start

参考书:王爽《汇编语言(第二版)》

0 0
原创粉丝点击