第六章 汇编语言

汇编语言

实方式执行环境

  1. 寄存器

    • 32位寄存器EAX、EBX、ECX、EDX、ESP、EBP、ESI和EDI

      16位寄存器AX、BX、CX、DX、SP、BP、SI和DI

      8位寄存器AH、AL、BH、BL、CH、CL、DH和DL

    • 段寄存器CS、DS、SS和ES,以及段寄存器FS和GS。寄存器CS含有当前代码段的段值,寄存器DS含有当前数据段的段值,寄存器SS含有当前堆栈段的段值。

    • 实方式下指令指针寄存器EIP中的高16位必须是0,相当于只有低16位的IP起作用

    • 实方式下堆栈指针寄存器ESP中的高16位必须是0,相当于只有低16位的SP起作用

  2. 指令集

存储器分段管理

  1. 存储器分段条件

    • 实方式下可访问的物理地址空间只有1M:00000H -- FFFFFH

    • 实方式下每个逻辑段必须满足如下两个条件:

      • 第一,逻辑段的起始地址必须是16的倍数
      • 第二,逻辑段的最大长度为64K
    • 存储段,既可以相连,也可以重叠

  2. 物理地址计算

    • 段起始地址有如下形式:bbbbbbbbbbbbbbbb0000

    • 20位段起始地址的高16位XXXX称为段值

    • 段起始地址与段值的关系:段起始地址 = 段值×16

    • 物理地址、段值和偏移之间关系:物理地址 = 段值×16 + 偏移

      例如:

             逻辑地址				  对应物理地址
            1234:3456                15796
            1234:34A8                157E8
            FFF0:0000                FFF00
      
    • 由于段可以重叠,一个物理地址可对应多个逻辑地址

  3. 段寄存器引用

    • 实方式下,段寄存器中的内容是段值

    • 代码段寄存器CS给出当前代码段的段值堆栈段寄存器SS给出当前堆栈段的段值数据段寄存器DS给出当前**缺省数据段的段值**。附加段寄存器ES、FS、GS也可以给出其他数据段的段值。

    • 每当需要产生一个20位的物理地址时,CPU会自动引用一个段寄存器获得段值,形成20位的段起始地址,再加上有效地址(偏移)。

      示例一:

      MOV   AX,0F000H
      MOV   DS,AX        ;DS含段值F000H
      MOV   ESI,0        ;使ESI为0(最低地址偏移为0)
      MOV   EAX,[ESI]    ;取出最低的4个字节 //起始地址默认为DS
      MOV   EDX,[ESI+4]  ;再取出次低的4个字节
      

      示例二:

      MOV   AX, 0F000H    ;对应源段的段值
      MOV   DS, AX        ;使DS含源数据段的段值
      MOV   AX, 0B800H    ;对应目标段的段值
      MOV   ES, AX        ;使ES含目标数据段的段值
      MOV   ESI, 0        ;ESI=0
      MOV   EDI, 2000H    ;EDI=2000H
      MOV   ECX, 8        ;ECX=8,作为循环计数
      NEXT:
          MOV   EAX, [ESI]     ;自动引用DS,偏移为ESI值    @here
          MOV   [ES:EDI], EAX  ;引用段寄存器ES,偏移为EDI值 @here
          ADD   ESI, 4
          ADD   EDI, 4
          LOOP  NEXT
      
  4. 16位存储器寻址方式

    • 16位的存储器寻址方式,主要应用于实方式。在实方式下,存储段的长度不超过64K,存储单元的有效地址是16位。

    • 16位有效地址EA可以有多种表示形式

基址部分可以是寄存器BX或BP;
变址部分可以是寄存器SI或DI;
位移量采用补码形式表示,在计算有效地址时,如位移量是8位,则被带符号扩展成16位

演示16位存储器寻址方式的使用:

略去操作数为8位/16位。

给出操作数是32位:

 ```asm
 MOV   EAX, [SI]
 ADD   EDX, [DI-4]
 SUB   [BX+DI], ECX
 MOV   [BX+SI+3], EAX
 ```

以下使用方式非法:

 ```asm
 MOV   EAX, [SI+DI]
 MOV   DX, [AX]
 MOV   [CX-3], AL
 ```

针对16位存储器寻址方式的取有效地址指令:

 ```asm
 MOV   DI, 1234H              ;DI=1234H
 MOV   BX, 16H                ;BX=0016H
 LEA   SI, [DI+BX+5]          ;SI=124FH
 LEA   EAX, [BX+DI-2]         ;EAX=00001248H
 ```

汇编语言源程序

  1. 系统功能调用

    系统功能类似于子程序。可以认为系统功能是由操作系统提供的子程序。

  2. 单个段的源程序

        segment   text      ;命名段text
        org   100H          ;段内偏移从100H开始计算
        ;
        
        ;代码内容
        
        MOV   AH, 4CH
        INT   21H           ;返回操作系统
        ;
    hello     db    "Hello world!", 0DH, 0AH, '$' ;一些数据
    

    演示程序dp61.asm

        segment   text      ;命名段text
        org   100H          ;段内偏移从100H开始计算
        ;
        MOV   AX, CS
        MOV   DS, AX        ;使数据段与代码段相同
        MOV   DX, hello     ;DX=hello的段内偏移
        MOV   AH, 9
        INT   21H           ;显示hello开始的字符串(以$结尾)
        ;
        MOV   AH, 4CH
        INT   21H           ;返回操作系统
        ;
    hello     db    "Hello world!", 0DH, 0AH, '$'
    
  3. 多个段的源程序

    整体框架

        segment   code                 ;定义段code
    .start:                           ;启动标号
        MOV   AX, stack
        MOV   SS, AX                   ;设置堆栈段寄存器
        MOV   SP, stacktop             ;设置堆栈顶
        ;
        MOV   AX, data
        MOV   DS, AX                   ;设置数据段寄存器
      
      	; 代码部分省略
      
        MOV   AH, 4CH
        INT   21H
        
    ;
    ;内部子程序
    ToASCII:                      ;子程序入口
        AND   AL, 0FH
        ADD   AL, '0'
        CMP   AL, '9'
        JBE   LAB3
        ADD   AL, 7
    LAB3:
        RET
    ;----------------------------------------------------------
        segment    data                 ;定义段data
    prompt    db   "Press a key: ",'$'
    newline   db   0DH,0AH,'$'
    result    db   0,0                  ;存放十六进制数ASCII码
              db   'H',0DH,0AH,'$'      ;结果字符串后半部分 
              ; 0ah和0dh组合起来是换行,$是字符串的结束标记
    ;----------------------------------------------------------
        segment
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值