认识保护模式之汇编复习2

来源:互联网 发布:软件配置文件用途 编辑:程序博客网 时间:2024/06/04 23:24

下面了解一下汇编语言怎么编写

伪指令:

汇编中主要分为汇编指令以及伪指令两种,汇编指令会转为相应的机器代码,伪指令不会,伪指令由编译器执行,编译器依据伪指令完成相应的编译工作。

assume 关键字  关联应用程序中的段

XXX segment


segment ends

只是一对的,表示汇编代码中的某一个段的代码

end  汇编程序结束

start 关键字,表示汇编程序的入口点在此

db 指令 define byte 

label db initalizer

msg db "hello world"


如果需要将hello world 利用汇编代码写入屏幕中,那么需要了解8086计算机的内存分布结构:

一台PC机中,装有多个存储器芯片,这些存储器芯片从物理连接上看是独立的、不同的器件。从读写属性上看分为两类:随机存储器(RAM)和只读存储器(ROM)。随机存储器可读可写,但必须带电存储,关机后存储的内容丢失;只读存储器只能读取不能写入,关机后其中的内容不丢失这些存储器从功能和连接上又可分为以下几类。

  1、随机存储器

  用于存放CPU使用的绝大部分程序和数据,主随机存储器一般由两个位置上的RAM组成,装在主板上RAM和扩展插槽上的RA    M。

  2、装有BIOS(基本输入/输出系统)的ROM

      BIOS是由主板和各类接口卡(如显卡、网卡等)厂商提供的软件系统,可以通过它利用该硬件设备进行最基本的输入输出。在主板和某些接口卡上插有存储相应BIOS的ROM。例如,主板上的ROM存储着主板的BIOS(通常称为系统的BIOS);显卡上的ROM中存储着显卡的BIOS;如果网卡上装有ROM,那其中就可以存储网卡的BIOS。

     3、接口卡上的RAM

     某些接口卡需要对大批量输入、输出数据进行暂时存储,在其上装有RAM。最典型的是显示卡上的RAM,一般称为显存。显示卡随时将显存中的数据向显示器上输出。换句话说,我们将需要显示的内容写入显存,就会出现在显示器上。

     下图展示了PC系统中各类存储器的逻辑连接情况。

      

     上述的那些存储器,在物理上是独立的器件,但是在以下两点上相同。

      都和CPU的总线相连。

      CPU对它们进行读或写的时候都通过控制线发出内存读写命令。

      这也就是说,CPU在操控它们的时候,把它们都当作内存来对待,把它们总的看作是一个由若干存储单元组成的逻辑存储器,这个逻辑存储器就是我们所说的内存地址空间。在汇编这门课中,我们所面对的是内存地址空间。

      下图展示了CPU将系统中各类存储器看作一个逻辑存储器的情况。

      

      在上图中,所有的物理存储器被看作是一个由若干存储单元组成的逻辑存储器,每个物理存储器在这个逻辑存储器中占有一个地址段,即一段地址空间。CPU在这段地址空间中读写数据,实际上就是在相对应的物理存储器中读写数据。

      内存地址空间的大小受CPU地址总线宽度的限制。8086CPU地址总线宽度为20,可以传送2^20个不同的地址信息,即可以定位2^20个内存单元,刚8086PC的内存地址空间大小为1MB。同理,80386CPU的地址总线宽度为32,则内存地址空间最大为4GB。

      这里有一个概念,我们平时所说的16位机,32位机其实是说它的CPU结构是16位或者32位的,这里的数字是在描述一个CPU的特征,而不是内存啊,地址总线,数据总线等等。

      如,16位结构即:运算器一次最多可以处理16位数据;寄存器的最大宽度为16位;寄存器和运算器这间的通路为16位。8086是16位结构的CPU,也就是说,在8086内部,能够一次性处理、传输、暂时存储的信息的最大长度是16位的。内在单元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放。

     我们在基于一个计算机硬件系统编程的时候,必须知道这个系统中的内存地址空间分配情况。因为当我们想在某类存储器中读写数据的时候,必须知道它的第一个单元的地址和最后一个单元的地址,才能保证读写操作是在预期的存储器中进行。比如,匀们希望向显示器输出一段信息,那么必须将这段信息写到显存中,显卡才能将它输出到显示器上。要向显存中写入数据,必须知道显存在内存地址空间中的地址。

     不同的计算机系统的内存地址空间的分配情况是不同的,下图展示了8086PC机内存地址空间分配的基本情况。

     上图告诉我们,从地址0~9FFFF的内存单元中读取数据,实际上就是在读取主随机存储器中的数据;向地址A0000~BFFFF的内存单元中写数据,就是向显存中写入数据,这些数据会被显示卡输出到显示器上;我们向地址C0000~FFFFF的内存单元中写入数据的操作是无效的,因为这等于改写只读存储器中的内容。

     内存地址空间:

     最终运行程序的是CPU,我们用汇编语言编程的时候,必须从CPU的角度考虑问题。对CPU来讲,系统中的所有存储器中的存储单元都处于一个统一的逻辑存储器中,它的容量受CPU寻址能力的限制。这个逻辑存储器即是我们所说的内存地址空间。

此时我们可以看出,显存的空间为A0000H-BFFFFH,其中查阅资料可知显卡的显存空间为:B8000H-BFFFFH,只需要将hello world字符串写到该显存地址空间即可。

该显示缓存区大小为32KB,可以显示25行,每行80字符,每个字符有256种属性(背景色、前景色、闪烁等组合信息)

这样,一个字符在缓冲区的显示需要两个字节,分别存放字符的ASCII码和属性。80×25模式下,一屏的内容在显示缓冲区中占4000字节。

显示缓存区分8页,每页4KB,一般情况下显示第0页的内容

对于每个字符,其低字节存放字符的ASCII码,高字节存放字符属性

vga B800F

 字体属性格式
7  6 5 4 3 2 1 0
BL R G B I R G B

闪烁背景色高亮前景色
红底绿字: 01000010B

显卡可以显示任意页内容一般情况下显示第0页内容即B8000H~B8F9FH

es,扩展段寄存器

不能直接给段寄存器赋值,应该先给通用寄存器赋值,然后再传给段寄存器

loop关键字
语法:
标号:  指令
       
指令2
       look
标号
cx
内部规定为loop的循环因子


以下代码为在屏幕上显示hello world:

assume cs:code,ds:data   ;关联相关的段,这里说明了有一个代码段,一个数据段

data segment
 db "hello world" 
data ends   ;数据段的定义

code segment  ;代码段
 start:        ;程序入口地址
 mov ax,data
 mov ds,ax  ;源数据地址  段地址
 mov bx,0b800h
 mov es,bx ;目标数据地址  段地址
 mov cx,11 ;循环次序
 mov si,0
 mov bx,0
 mov ah,01000010b;说明字符属性
  s:

   mov al,ds:[si]
    mov es:[bx],ax
    mov es:[bx+1],ah
    inc si
    add bx,2
    loop s
   
    mov ax,4c00h
    int 21h  调用中断显示字符
   
code ends代码段结束
end start程序结束

使用Windows下的汇编开发环境

masm for windows

其运行效果如下:



原创粉丝点击