zoukankan      html  css  js  c++  java
  • 灵活定位内存地址

     and 和 or 指令

    1、and 指令:逻辑与指令,按位进行与运算。
    mov al , 01100011B
    and al ,  00111011B      ; 结果00100011B
    可以用来将操作对象的相应位设为 0 ,其他位不变。
    2、or 指令:逻辑或指令,按位进行或运算。
    mov al , 01100011B
    or al ,     00111011B     ; j结果01111011B
    可以用来将操作对象的相应位设置为 1 ,其他位不变。




    计算机中的 ASCII 码

    编码规则,文本编辑过程就是按照ASCII码规则进行的编码和解码。当我们按下键盘的一个 a ,这个按键信息被送入计算机,计算机用ASCII码规则对其进行编码,将其转化为61H存储在内存指定空间;文本编辑软件取出内存中的61H,将其送到显卡的显存中;工作在文本模式下的显卡,用ASCII码规则解释显存中的内容,61H被当做字符“a”,显卡驱动显示器,将字符“a”的图像画在屏幕上。




    以字符形式给出的数据

    在汇编程序中,用‘...’的方式指明数据是以字符的形式给出的,编译器把它们转化为相应的 ascii 。
    assume ds:data , cs:code
    data segment
         db 'unIX'
         db 'foRK'
    data ends
    code segment
    start:    mov al , 'a'
                 mov bl , 'b'
                 mov ax , 4c00h
                 int 21h
    code ends
    end start
    db 'unIX' 相当于“db 75h , 6eh , 49h , 58h”
    db 'foRK' 相当于“db 66h , 6fh , 52h , 4bh”
    mov al , 'a' 相当于 "mov al , 61h"

      // 这个程序运行第一条指令指向mov al 'a' ;数据肯定存放在这条指令的上面,就是 076A:0

    ;定义程序,把字符串的大写改小写,小写改大写
    assume cs:codesg , ds:datasg
    datasg segment
            db 'BaSic'
            db 'iNfOrMaTion'
    datasg ends
    codedg segment
    start:   mov ax , datasg                  ;设置 ds 指向 datasg 段 ;这条指令执行的同时,系统就把数据段的空间分配好了
                mov ds , ax
                mov bx , 0                           ;设置(bx)=0,ds:bx指向 'BaSic' 的第一个字母
                mov cx , 5          
    s:         mov al , [bx]                        ;取出 'B'  放到 al 中
               and al , 11011111B            ;转换,因为大写和小写字母只是二进制的第5位不一样;小写字母第5位为1,改成0就变成相应的大写
               mov [bx] , al                        ;转换完成,写回原单元。
               inc bx                                   ;偏移一位,指向下一个字母
               loop s
               mov bx , 5                            ;设置偏移,指向'iNfOrMaTiOn'的第一个字母
               mov cx , 11                          ;设置循环次数11
    s0:      mov al , [bx]
               or al , 00100000B               ;大写字母变小写字母
               mov [bx] , al
               inc bx
               loop s0
               mov ax , 4c00h
               int 21h
    codesg ends
    end start
           






    [bx+idata]

    表示一个内存单元,偏移地址是(bx)+idata
    eg:mov ax , [bx+200]    ; 将一个内存单元的内容送入 ax , 这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为 bx 中的数值加上 200,段地址在 ds 中。
    mov ax , [200+bx]
    mov ax , 200[bx]
    mov ax , [bx].200  ;立即数不在最开头就要前面加一个.





    [bx+idata]的方式进行数组的处理

    改写上面那个程序字符大写改小写,小写改大写的程序
    assume cs:codesg , ds:datasg
    datasg segment
            db 'BaSic'
            db 'iNfOrMaTion'
    datasg ends
    codesg segment
    start :     mov ax , datasg
                 mov ds , ax
                 mov bx , 0
                 mov cx , 5
    s:           mov al , [bx]
                 and al , 11011111B
                 mov [bx] , al
                 mov al , [5+bx]
                 or al , 00100000B
                 mov [5+bx] , al                        ; 第一次5次循环直接可以同时操作两个串,如果两个字符串一样效率更高
                 inc bx
                 loop s
                 mov cx , 6
                 inc bx
    s0:        mov al , [5+bx]                          ; 处理较长的字符串剩下的字符
                 or al , 00100000B
                 loop s0

                mov ax , 4c00h
                int 21h
    codesg ends
    end start





    SI 和 DI

    SI 和 DI 是8086CPU中和 bx 功能相近的寄存器,SI 和 DI 不能够分成两个 8 位寄存器来使用
     SI:源变址寄存器;   DI:目的变址寄存器;
    mov bx , 0
    mov ax , [bx]
    mov si , 0
    mov ax , [si]
    mov di
    mov ax , [di]
    *3组指令效果一样
    ;用 SI 和 DI 寄存器来实现将字符串 'welcome to masm!' 复制到它后面的数据区
    assume cs:codesg , ds:datasg
    datasg segment
              db 'welcome to masm!'
              db '................'
    datasg ends
    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               ;si 和 di 不能分成两个8寄存器,所以一次拷贝会拷贝16位2个字节,每次循环+2
                add di , 2
                loop s
                mov ax , 4c00h
                int 21h
    codesg ends
    end start
    tips:start后面紧更着冒号
        





    [bx+si] 和 [bx+di]




    [bx+si+idata] 和 [bx+di+idata]

    mov ax , [bx+200+si]
    mov ax , [200+bx+si]

    mov ax , 200[bx][si]
    mov ax , [bx].200[si]
    mov ax , [bx][si].200

    ;将datasg段中的每个单词改为大写字母
    assume cs:codesg , ds:datasg
    datasg segment
            db 'ibm             '
            db 'dec             '
            db 'dos             '
            db 'vax             '
    datasg ends
    codesg segment
    start:       mov ax , datasg
                    mov ds , ax
                    mov bx , 0
                    mov cx , 4
    s0:           mov dx , cx      ;暂存外层循环cx的值
                    mov si , 0 
                    mov cx , 3       ;cx设置为内层循环的次数
    s:              mov al , [bx+si]
                    and al , 11011111B
                    mov [bx+si] , al
                    inc si 
                    loop s
                    add bx , 16
                    mov cx , dx     ;恢复外层循环cx的值
                    loop s0
    codesg ends
    end start
    ; 程序每次修改一行的字符,然后转到下一行,所以用到两个循环,不得不暂存cx的值,但是cpu的寄存器是有限的;如果寄存器不够用,最好的办法是用一个指定的内存地址来暂存数据,ds:[idata];但是最好还是用栈来存放
    ;优化
    assume cs:codesg , ds:datasg , ss:stacksg
    datasg segment
            db 'ibm             '
            db 'dec             '
            db 'dos             '
            db 'vax             '
    datasg ends 
    stacksg segment      ; 用栈段来存放临时数据
           dw 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
    stacksg ends
    codesg segment
    start:       mov ax , stacksg
                    mov ss , ax
                    mov sp , 16
                    mov ax , datasg
                    mov ds , ax
                    mov bx , 0
                    mov cx , 4
    s0:           push cx     ;栈段暂存外层循环cx的值
                    mov si , 0
                    mov cx , 3     ;cx设置为内层循环的次数
    s:              mov al , [bx+si]
                    and al , 11011111B
                    mov [bx+si] , al
                    inc si
                    loop s
                    add bx , 16
                    pop cx        ;恢复外层循环cx的值
                    loop s0
    codesg ends
    end start






  • 相关阅读:
    Azure 存储简介
    Databricks 第6篇:Spark SQL 维护数据库和表
    Databricks 第5篇:Databricks文件系统(DBFS)
    Databricks 第4篇:pyspark.sql 分组统计和窗口
    IDEA分析JAVA内存溢出和内存泄漏
    Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Connection is broken: "session closed" [90067-200] 解决
    Java 中初始化 List 集合的 8 种方式!
    java list算法问题(给定一 int 数组返回倒序的最大连续递增的区间(至少大于等于2)数组倒序)
    uni-app知识点:页面滚动到指定位置(即锚点实现)、设置背景颜色backgroundColor无效的问题、导航栏设置角标及动态控制修改角标数字
    @Transactional注解为什么不生效
  • 原文地址:https://www.cnblogs.com/meihao1203/p/7546053.html
Copyright © 2011-2022 走看看