• [汇编语言]数据处理的两个基本问题



    一、bx、si、di和bp

    之后为了描述上的简便,之后我们使用两个描述性的符号reg来表示一个寄存器,用sreg表示一个段寄存器

    reg包括:ax、bx、cx、dx、sp、bp、si、di等
    sreg包括:ds、ss、cs、es

    在8086中,只有这4个寄存器(bx、si、di、bp)可以用在[…]中来进行内存单元的寻址,比如以下几种都是正确的

    正确:
    mov ax,[bx]
    mov ax,[bx+si]
    mov ax,[bp]
    mov ax,[bp+di]
    错误:
    mov ax,[cx]
    mov ax,[ax]
    mov ax,[dx]
    mov ax,[ds]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在[…]中,这4个寄存器(bx、si、di、bp)可以单独出现或只能以4种组合出现:bx和si、bx和di、bp和si、bp和di

    只要在[…]中使用了寄存器bp,而且指令没有显示给出段地址,则段地址默认就在ss中

    机器指令处理的数据在什么地方
    绝大多数机器指令都是进行数据处理的指令,按理来说分别3类:读取、写入、运算,并不关心数据的值是多少,要处理的数据可以在3个地方:CPU内部、内存、端口


    二、汇编语言中数据位置的表达

    1. 立即数(idata)
      对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中)在汇编语言称为立即数(idata),在汇编语言中直接给出

    如:

    mov ax,1
    add bx,2000h
    or bx,00010000b
    mov al,'a'
    
    • 1
    • 2
    • 3
    • 4
    1. 寄存器

    指令要处理的数据在寄存器中,在汇编语言中给出相应的寄存器名

    mov ax,bx
    mov ds,ax
    
    • 1
    • 2
    1. 段地址(SA)和偏移地址(EA)

    指令要处理的数据在内存中,在汇编指令中可用[x]给出,EA和SA在某个段寄存器中

    mov ax,[0]
    mov ax,[di]
    mov ax,ds:[bp]
    
    • 1
    • 2
    • 3

    三、指令要处理的数据有多长

    8086CPU的指令,可用处理byte和word。所以在机器指令中药指明是字操作还是字节操作,在汇编语言中,用以下方式进行表示

    1. 通过寄存器名来指明要处理的数据尺寸
    mov ax,1 ;字操作
    mov al,1 ;字节操作
    
    • 1
    • 2
    1. 没有寄存器名存在的情况下,用操作符 X ptr指明内存单元的长度,X在汇编指令中可以为word或是byte
    下面指令中,用word ptr指明了访问的内存单元是一个字单元
    mov word ptr ds:[0],1
    inc word ptr [bx]
    下面指令中,用byte ptr指明了访问的内存单元是一个字节单元
    mov byte ptr ds:[0],1
    inc byte ptr [bx]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在没有寄存器参与的内存单元访问指令中,用word ptr或是byte ptr显性的指明要访问的内存单元的长度是很有必要的,不然cpu无法得知要访问的单元是字单元还是字节单元


    四、div指令

    div是除法指令,使用div做除法的时候应该注意以下问题:

    1. 除数:有8位和16位两种,在一个reg或内存单元中
    2. 被除数:默认放在AX或DX和AX中,如果除数为8位,被除数就是16位,如果除数为16位,被除数就是32位,在DX和AX中存放,DX存放高16位,AX存放低16位
    3. 结果:如果除数为8位,AL存放除数操作的商,AH存放余数,如果为16位,AX存放商、DX存放余数

    格式如下:
    div reg
    div 内存单元

    现在我们可以用多种方法来表示内存单元:比如下面的例子

    div byte ptr ds:[0]
    含义:
    (al)=(ax)/((ds)*16+0)的商
    (ah)=(ax)/((ds)*16+0)的余数
    
    div word ptr es:[0]
    含义:
    (ax)=[(dx)*10000H + (ax)]/((es)*16+0)的商
    (dx)=[(dx)*10000H + (ax)](ax)/((ds)*16+0)的余数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    编程,利用除法计算100001/100

    首先被除数>65535,不能用ax寄存器存放,所以我们用dx和ax两个寄存器联合存放100001,除数小于255,可以存放在一个8位寄存器中,但是因为被除数是32位的,所以除数应该是16位的,我们要用一个16位寄存器来存放

    100001表示为16进制是:186A1H。程序如下:

    mov dx,1
    mov ax,86A1H ; (dx)*10000H+(ax) = 100001
    mov bx,100 ;除数
    div bx ;格式:div 除数
    
    • 1
    • 2
    • 3
    • 4

    程序执行后,(ax)= 03E8H,(dx)= 1

    编程,利用除法计算1001/100

    mov ax,1001
    mov bl,100
    div bl
    
    • 1
    • 2
    • 3

    五、伪指令dd

    前面我们使用db和dw定义字节型数据和字型数据,dd是用来定义(double word,双字)型数据的,比如:

    data segment
    dd 1
    dw 1
    dw 1
    data ends
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第一个数据为01H,在data:0处,占1个字节
    第二个数据为01H,在data:1处,占1个字
    第三个数据为01H,在data:3处,占2个字


    六、dup

    dup是一个操作符,与db、dw、dd等一样,也是由编译器识别处理的符号,他和db、dw、dd等数据定义伪指令配合使用,用来进行数据的重复

    db 3 dup (0)定义了3个字节,他们的值都是0,相当于是db 0,0,0

    db 3 dup(0,1,2)定义了9个字节,他们是0、1、2、0、1、2、0、1、2

    可见dup的使用格式如下:

    db 重复的次数 dup (重复字型数据)
    
    • 1
  • 相关阅读:
    mannose-OH|甘露糖-羟基|mannose-PEG-OH|甘露糖-聚乙二醇-羟基
    干货 | 携程鸿蒙应用开发实践
    全真模拟题!PMP提分必练
    【嵌入式系统设计与实现】4 十字路口交通灯控制(简易版)
    Tomcat中间件打印请求日志
    以深圳为例Python一键生成核酸检测日历
    Unity技术手册-UGUI零基础详细教程-Toggle切换
    SQL 增删改查
    Python数据挖掘 | 升级版自动查核酸
    Spring的三种依赖注入的方式
  • 原文地址:https://blog.csdn.net/weixin_51304981/article/details/126727969