• 汇编学习笔记(4)寻址方式


    前言

    本文是《汇编语言》的学习笔记,对应书中第七章内容,灵活的寻址方式。

    这一章节主要通过例题的形式介绍汇编中访问内存的多种方式,新介绍了and和or命令,si,di寄存器。

    and

    and命令是逻辑与命令,按二进制位进行与运算。与运算就是q与q的合取式记为p^q,p和q只要有一个为假,p^q就为假,当且仅当q和q都为真时,p^q才为真。用二进制表示,当且仅当p和q都为0时,p^q才为0,所以

    mov al,01100000b

    and al,00110000b

    结果等于00100000b.

    or

    or命令是逻辑或命令,按二进制位进行或运算。或运算就是q或q的析取式记为pVq,p或q只要有一个为真,pVq就为真,当且仅当q和q都为假时,pVq才为假。用二进制表示,当且仅当p和q都为1时,pVq才为1,所以

    mov al,01100000b

    or al,00110000b

    结果等于01110000b.

    si和di

    si和di是8086CPU中和bx功能相近的寄存器,不同的是si和di不能拆分为两个8位寄存器,即没有sh,sl,dh,dl,si和di多和bx搭配表示地址。

    内存地址的表示方式

    程序的设计大部分是对数据的处理,数据一般存储在内存当中,所以对内存单元的寻址能力尤其重要。数据段的段地址一般保存在寄存器ds中,故在偏移地址的表示方面可以有多种方式,假设ds=1000h

    1.[idata],设idata=10h,则内存单元地址为ds:[10]=10010h

    2.[bx],设(bx)=10h,则内存单元地址为ds:[bx]=10010h

    3.[bx+idata],idata[bx],[bx].idata,设(bx)=10h,idata=10h,则内存单元地址为ds:[bx+idata]=10020h

    4.[bx+si],[bx+di],[bx][si],[bx][di],设(bx)=10h,(si)=10h,则内存单元地址为ds:[bx][si]=10020h

    5.[bx+si+idata],[bx+di+idata],idata[bx][si],idata[bx][di],设(bx)=10h,(si)=10h,idata=10h,则内存单元地址为ds:idata[bx][si]=10030h

    几个例子

    • 将小写字符改为大写,大写字符改为小写
     1 ;将第一个字符串变为大写,第二个字符串变为小写
     2 
     3 assume cs:code,ds:data
     4 
     5 data segment
     6     db 'unix'
     7     db 'FORK'
     8 data ends
     9 
    10 code segment
    11 start:  mov ax,data
    12         mov ds,ax
    13         mov bx,0
    14         mov cx,4
    15 s:      mov al,0[bx];等同[bx+0]
    16         and al,11011111b;与运算,第五位置为0,大写
    17         mov 0[bx],al
    18         mov al,4[bx];偏移地址为bx+4,内存地址为(ds)*16+(bx)+4
    19         or al,00100000b;或运算,第五位置为1,小写
    20         mov 4[bx],al
    21         inc bx
    22         loop s
    23 
    24         mov ax,4c00h
    25         int 21h
    26 
    27 code ends
    28 
    29 end start

    大家可以看到上面的例子中,偏移地址的表示方式0[bx],5[bx]和C语言中的数组表示array[0],array[5]非常相像,C语言的数组可以理解为对数组首元素的偏移量。

    • 将字符串的首字母大写
     1 ;将字符串首字母大写
     2 
     3 assume cs:code,ds:data
     4 
     5 data segment
     6     db '1.file          '
     7     db '2.folder        '
     8     db '3.path          '
     9 data ends
    10 
    11 code segment
    12 start:  mov ax,data
    13         mov ds,ax
    14         mov bx,0
    15         mov si,2
    16         mov cx,3
    17 s:      mov al,[bx][si]
    18         and al,11011111b
    19         mov [bx][si],al
    20         add bx,16
    21         loop s
    22 
    23         mov ax,4c00h
    24         int 21h
    25 
    26 code ends
    27 
    28 end start

    • 将每个字符串改为大写字母
     1 ;将字符串改为大写
     2 
     3 assume cs:code,ds:data,ss:stack
     4 
     5 data segment
     6     db 'file            '
     7     db 'name            '
     8     db 'path            '
     9 data ends
    10 
    11 stack segment
    12     dw 0,0,0,0,0,0,0,0
    13 stack ends
    14 
    15 code segment
    16 start:  mov ax,stack
    17         mov ss,ax
    18         mov sp,16;指向栈顶
    19         mov ax,data
    20         mov ds,ax
    21         mov bx,0
    22         mov cx,3
    23 s:      push cx
    24         mov si,0 
    25 
    26         mov cx,4
    27 s0:     mov al,[bx][si]
    28         and al,11011111b
    29         mov [bx][si],al
    30         inc si
    31         loop s0
    32 
    33         pop cx
    34         add bx,16
    35         loop s
    36 
    37         mov ax,4c00h
    38         int 21h
    39 
    40 code ends
    41 
    42 end start

  • 相关阅读:
    vim的额外功能
    vi的使用
    文件与文件系统的压缩
    其他常用的压缩与备份工具
    光盘写入工具
    XFS 文件系统的备份与还原
    打包命令:tar
    Linux 系统常见的压缩命令
    Windows10修改DNS
    Linux 磁盘与文件系统管理
  • 原文地址:https://www.cnblogs.com/michaelle/p/4023315.html
Copyright © 2020-2023  润新知