zoukankan      html  css  js  c++  java
  • 更灵活的定位内存地址的方法01 零基础入门学习汇编语言32

    第七章:更灵活的定位内存地址的方法01

     

    让编程改变世界

    Change the world by program


     

    引言

    前面,我们用[0]、[bx]的方法,在访问内存的指令中,定位内存单元的地址。 在这一章中,我们主要讲解一些更灵活的定位内存地址的方法和相关的编程方法。 我们的讲解将通过具体的问题来进行。  

    and指令和or指令

    首先我们介绍两条指令and和or,因为我们下面的例程中要用到它们。  

    and指令:逻辑与指令,按位进行与运算。

    mov al, 01100011B

    and al, 00111011B

    执行后

    al = 00100011B

    and指令的功能

    通过该指令可将操作对象的相应位设为0,其他位不变。 例如:

    将al的第6位设为0:and al, 10111111B

    将al的第7位设为0:and al, 01111111B

    将al的第0位设为0:and al, 11111110B

     

    or 指令:逻辑或指令,按位进行或运算。

    mov al, 01100011B

    and al, 00111011B

    执行后

    al = 01111011B

    or指令的功能

    通过该指令可将操作对象的相应位设为1,其他位不变。 例如:

    将al的第6位设为1:and al, 01000000B

    将al的第7位设为1:and al, 10000000B

    将al的第0位设为1:and al, 00000001B

     

    关于ASCII码

    世界上有很多编码方案,有种方案叫做ASCII编码,是在计算机系统中通常被采用的。 简单地说,所谓编码方案,就是一套规则,它约定了用什么样的信息来表示现实对象。 比如说,在ASCII编码方案中,用 61H 表示“a”,62H表示“b”。   一种规则需要人们遵守才有意义。 一个文本编辑过程中,就包含着按照ASCII编码规则进行的编码和解码。 在文本编辑过程中,我们按一下键盘的a键,就会在屏幕上看到“a”。这是怎样一个过程呢?  

    以字符形式给出的数据

    我们可以在汇编程序中,用 “……”的方式指明数据是以字符的形式给出的,编译器将把它们转化为相对应的ASCII码。 请看以下程序 [codesyntax lang="asm"]
    assume ds:data
    
    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
    [/codesyntax] 上面的源程序中: “db ‘unIX’ ” 相当于“db 75H,6EH,49H,58H”, “u”、 “n”、 “I”、 “X”的ASCII码分别为75H、6EH、49H、58H; “db ‘foRK’ ” 相当于“db 66H,6FH,52H,4BH”, “u”、 “n”、 “I”、 “X”的ASCII码分别为66H、6FH、52H、4BH; “mov al,’a’”相当于“mov al,61H”,”a”的ASCII码为61H; “mov al,’b’”相当于“mov al,62H”,”b”的ASCII码为62H。

    大小写转换的问题

      首先分析一下,我们知道同一个字母的大写字符和小写字符对应的 ASCII 码是不同的,比如 “A” 的 ASCII 码是41H,“a”的ASCII码是61H。 要改变一个字母的大小写,实际上就是要改变它所对应的ASCII 码。 我们可以将所有的字母的大写字符和小写字符所对应的ASCII码列出来,进行对比,从中找到规律。 大写     二进制        小写      二进制 A    01000001      a       01100001 B     01000010      b      01100010 C     01000011       c      01100011 D     01000100      d      01100100 通过对比,我们可以看出来,小写字母的ASCII码值比大写字母的ASCII码值大20H 。 这样,我们可以想到,如果将 “a” 的ASCII码值减去20H,就可以得到“A”;如果将“A”的ASCII码值加上20H 就可以得到“a”。  

    按照这样的方法,我们可以将 datasg段中:

    第一个字符串“BaSiC”中的小写字母变成大写;

    第二个字符串,“iNfOrMaTiOn”中的大写字母变成小写。

      要注意的是:对于字符串“BaSic”,我们应只对其中的小写字母所对应的ASCII码进行减20H 的处理,将其转为大写,而对其中的大写字母不进行改变。 另外还要注意的是: 对于字符串 “ iNforMaTIOn ” ,我们应只对其中的大写字母所对应的ASCII码进行加20H 的处理,将其转为小写。而对于其中的小写字母不进行改变,这里面就存在着一个前提,程序必须要能够判断一个字母是大写还是小写。 [codesyntax lang="asm"]
    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]
    
        如果(al)>61H,则为小写字母ASCII码,则:sub al,21H
    
        mov [bx],al
        inc bx
        loop s
    
        :
    [/codesyntax]   判断将用到一些我们目前还没有学习到的指令。现在面临的问题是,用己学的指令来解决这个问题,则我们不能对字母的大小写进行任何判断。 但是,现实的问题却要求程序必须要能区别对待大写字母和小写字母。   可以看出,就ASCII码的二进制形式来看,除第5位(位数从0开始计算)外,大写字母和小写字母的其他各位都一样。 大写字母ASCII码的第5位(位数从0开始计算)为0,小写字母的第5位为1。   这样,我们就有了新的方法: 一个字母,我们不管它原来是大写还是小写,我们将它的第5位置0,它就必将变为大写字母,将它的第5位置1,它就必将变为小写字母。 我们用什么方法将一个数据中的某一位置0还是置1? 当然是用我们刚刚学过的or和and指令。   完整的程序代码 [codesyntax lang="asm"]
    assume cs:codesg,ds:datasg
    datasg segment
        db 'BaSiC'
        db 'iNfOrMaTiOn'
    datasg ends
    
    codesg segment
    start: mov ax,datasg
           mov ds,ax		;设置ds指向datasg段
    
           mov bx,0			;设置(bx)=0,ds:bx指向“BaSiC”的第一个字母
    
           mov cx,5			;设置循环次数5,因为“BaSiC”的有5个字母
        s: mov al,[bx]		;将ASCII码从ds:bx所指向的单元中取出
           and al,11011111b		;将al中的ASCII码的第5位置为0,变为大写字母
           mov [bx],al		;将转变后的ASCII码写回原单元
    
           inc bx			;(bx)加1,ds:bx指向下一个字母
           loop s
    
           mov bx,5			;设置(bx)=5,ds:bx指向“iNfOrMaTiOn”的第一个字母
    
           mov cx,11		;设置循环次数11,因为“iNfOrMaTiOn”的有11个字母
       s0: mov al,[bx]
           or al,00100000b		;将al中的ASCII码的第5位置为0,变为小写字母
           mov [bx],al
           inc bx
           loop s0
    
           mov ax,4c00h
           int 21h
    codesg ends
    end start
    [/codesyntax] [buy] 获得所有教学视频、课件、源代码等资源打包 [/buy] [Downlink href='http://kuai.xunlei.com/d/LPXZADYHUTIN']视频下载[/Downlink]
  • 相关阅读:
    二级联动选择框的实现
    vimperator
    Ipan笔记-2
    git的一些补充点
    联想云部署的笔记心得
    关于vim的折叠
    ipan笔记
    php中浮点数计算问题
    Chrome 控制台报错Unchecked runtime.lastError: The message port closed before a response was received
    PHP-redis中文文档
  • 原文地址:https://www.cnblogs.com/LoveFishC/p/3846011.html
Copyright © 2011-2022 走看看