• 转:汇编寄存器的使用


    一、汇编语言中,为什么SI和DI不能同时使用汇编 
    其实你可以想一下,这两个寄存器的意思,SI源变址寄存器,DI目地变址寄存器,既然是变址寄存器,那么他们肯定是在某个地址的基础上进行偏移变化,由此我们就得出了需要基址寄存器。 
    你要是把这两个寄存器同时使用,那你地址变化的基址都没有,你该怎么变化呢?你在谁的基础上变化(也就是地址偏移)? 
    对于这些汇编中的规定,其实有时并不需要书上详细的介绍,我们都应该可以从中推导出这些规则,书上的那些介绍个人认为只是用来验证我们的推测的。或是对我们所掌握的知识的进行检测,用来说明我们所掌握的是对的! 


    1:数据寄存器,一般称之为通用寄存器组 

         8086 有8个8位数据寄存器, 
         这些8位寄存器可分别组成16位寄存器: 
         AH&AL=AX:累加寄存器,常用于运算; 
         BH&BL=BX:基址寄存器,常用于地址索引; 
         CH&CL=CX:计数寄存器,常用于计数; 
         DH&DL=DX:数据寄存器,常用于数据传递。 

       2:地址寄存器/段地址寄存器 

         为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址: 
         CS(Code Segment):代码段寄存器; 
         DS(Data Segment):数据段寄存器; 
         SS(Stack Segment):堆栈段寄存器; 
         ES(Extra Segment):附加段寄存器。 

    3:特殊功能的寄存器 

         IP(Instruction Pointer):指令指针寄存器,与CS配合使用,可跟踪程序的执行过程; 
         SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置。 
         BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置; 
         SI(Source Index):源变址寄存器可用来存放相对于DS段之源变址指针; 
         DI(Destination Index):目的变址寄存器,可用来存放相对于 ES 段之目的变址指针。 

    二、si,di使用的例子 
    SIDI是8086CPU中和bx功能相近的寄存器,SIDI不能够分成两个8位寄存器来使用. 

    下面三组指令实现了相同的功能: 

    (1) mov bx,0 

          mov ax,[bx] 

    (2) mov si,0 

          mov ax,[si] 

    (3) mov di,0 

          mov ax,[di] 

    下面的三组指令也实现了相同的功能: 

    (1) mov bx,0 

    mov ax,[bx+123] 

    (2) mov si,0 

    mov ax,[si+123] 

    (3) mov di,0 

    mov ax,[di+123] 

    用寄存器SI和DI实现将字符串 'welcome to masm!' 复制到它后面的数据区中. 

    assume cs:codesg,ds:datasg 
    
    datasg segment 
    
    db 'welcome to masm!' 
    
    db '............................' 
    
    datasg ends 


    分析: 

    我们编写的程序大都是进行数据的处理,而数据在内存中存放,所以我们在处理数据之前首先要搞清楚数据存储在什么地方,也就是说数据的内存地址.现在我们要对datasg段中的数据进行复制,我们先来看以下要复制的数据在什么地方, 

    datasg:0,这是要进行复制的数据的地址.那么复制到那里去呢?它后面的数据区.'welcome to masm!'从偏移地址0开始存放,长度为16个字节,所以,他们后面的数据区的偏移地址为16,就是字符串所要存放的空间,清楚了地址之后,我们就可以进行处理了.我们的ds:si指向要复制的原始字符串,用ds:di指向复制的目的空间,然后一个循环来完成复制, 

    代码如下: 

    codesg segment 
    
    start:mov ax,datasg 
    
    mov ds,ax 
    
    mov si,0 
    
    mov di,16 
    
    mov cx,8 
    
    s:mov ax,[si] 
    
    mov [di],ax 
    
    add si,2 
    
    add di,2 
    
    loop s 
    
    mov ax,4c00H 
    
    int 21H 
    
    codesg ends 
    
    end start 

    注意在程序中, 我们用的16位寄存器进行内存单元之间的数据传送,一次复制2个字节,一共循环8次(si和di每次加2)

    用更少的代码,实现: 

    分析: 

    我们可以利用[bx(si或di)+idata]的方式,来使程序变得简洁.如下: 

    codesg segment 
    
    start:mov ax,datasg 
    
    mov ds,ax 
    
    mov si,0 
    
    mov cx,8 
    
    s:mov ax,0[si] 
    
    mov 16[ax],ax 
    
    add si,2 
    
    loop s 
    
    mov ax,4c00H 
    
    int 21H 
    
    codesg ends 
    end start 
  • 相关阅读:
    管道及有名管道(pipe与FIFO)
    详细介绍Linux重定向的使用
    Emacs文件和目录操作模式Dired
    exec家族函数
    Seven file types of Unix system(4.3)
    va_list、va_start、va_arg、va_end的原理与使用
    const int*和int const*的区别
    asp.net 文件加载错误
    终于有了属于自己的家,哈哈,很高兴~~
    难得的一场雪
  • 原文地址:https://www.cnblogs.com/youxin/p/2526067.html
Copyright © 2020-2023  润新知