8086汇编-32更灵活定位内存地址01

#pragma once

/*32-更灵活定位内存地址01

引言

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

我们的讲解将通过具体的问题来进行。

and和or指令

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

(1)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

(2)or 指令:逻辑"或"指令,按位进行"或"运算。

如 mov al, 01100011B

or al, 00111011B

执行后: al = 01111011B

or指令的一点功能

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

例如:

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

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

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

关于ASCII码

世界上有很多编码方案,有种方案叫做ASCII编码,是在计算机系统中通常被采用的。

简单地说,所谓编码方案,就是一套规则,它约定了用什么样的信息来表示现实对象。

比如说,在ASCII编码方案中,用 61H 表示“a”,62H表示“b”。

一种规则需要人们遵守才有意义。

一个文本编辑过程中,就包含着按照ASCII编码规则进行的编码和解码。

在文本编辑过程中,我们按一下键盘的a 键,就会在屏幕上看到“a”。 --- (十进制中,英文大小写之间相差32个数字,例如A对应65 那么a 就对应97,十六进制则相差20H,换算成十进制也是32哦.)

这是怎样一个过程呢?

以字符形式给出的数据

我们可以在汇编程序中,用 '……'的方式(' '是这两个单引号,不是......)指明数据是以字符的形式给出的,编译器将把它们转化为相对应的ASCII码。

请看以下程序:

        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                

我们来分析一下……

上面的源程序中:(db 是定义字节型数据,dw 是定义字型数据.ASCII 码使用 字节型数据定义就够用了,所以没有用dw,毕竟对照表里面对应的16位数字都是2位的,1个16位数据占用4位,2个16进制数据就是8位=1字节)

“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 。 而且还可以看出来,二进制中,用一个字母 大写和小写 在第5位(位数从0开始计算)差了1,也就是20H. 这是个窍门~

这样,我们可以想到,如果将 “a” 的ASCII码值减去20H,就可以得到“A”;如果将“A”的ASCII码值加上20H 就可以得到“a”。

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

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

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

要注意的是:

对于字符串“BaSic”,我们应只对其中的小写字母所对应的ASCII码进行减20H 的处理,将其转为大写,而对其中的大写字母不进行改变;

另外还要注意的是:

对于字符串 “ iNforMaTIOn ” ,我们应只对其中的大写字母所对应的ASCII码进行加20H 的处理,将其转为小写;

而对于其中的小写字母不进行改变,这里面就存在着一个前提,程序必须要能够判断一个字母是大写还是小写。

以“BaSiC”讨论,程序的流程将是这样的:

        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,20H                 ;这里的如果,是因为我们还没有学习判断怎么写,暂时用中文代替演示.
               mov [bx],al
               inc bx
               loop s
:

大小写转换的问题

判断将用到一些我们目前还没有学习到的指令。现在面临的问题是,用己学的指令来解决这个问题,则我们不能对字母的大小写进行任何判断。

但是,现实的问题却要求程序必须要能区别对待大写字母和小写字母。

可以看出,就ASCII码的二进制形式来看,除第5位(位数从0开始计算)外,大写字母和小写字母的其他各位都一样。

大写字母ASCII码的第5位(位数从0开始计算)为0,小写字母的第5位为1。

这样,我们就有了新的方法:

一个字母,我们不管它原来是大写还是小写:

我们将它的第5位置0,它就必将变为大写字母;

将它的第5 位置1,它就必将变为小写字母。

我们用什么方法将一个数据中的某一位置0还是置1?

当然是用我们刚刚学过的or和and指令。

完整的程序代码 (把'BaSiC'字母变成大写,把'iNfOrMaTiOn'字母变成小写)

        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                         ; 偏移从0开始
               mov cx,5                         ; 5个字母表示5个字节
           s0: mov al,[bx]
               and al,11011111B                 ; 这里计算后的值赋予的是al 的地址内存,并不是段.
               mov [bx],al                      ; 改变值后赋值到真实原本的地址中
               inc bx
               loop s0
    
               mov bx,5                         ; 偏移从5开始
               mov cx,11                        ; 11个字母表示11个字节
           s1: mov al,[bx]
               or  al,00100000B                 ; 如果该位数是1那么就不会有变化,如果不是那么就强制人它是!!!
               mov [bx],al
               inc bx
               loop s1
               mov ax,4c00H
               int 21H
        codesg ends
        end start

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值