汇编语言——更灵活的定位内存地址的方法

and和or指令

1、and指令

将2进制中的1当做真,2进制中的0当做假

则:只有2个事件都为真的时候才为真,即1&&1==>1,1&&0==>0,0&&0==>0;

用处:假如想把一个数的第7位变成0,让它和01111111B执行与操作就好了

1 mov al,10001101B    ; 8位数据
2
3 add al,01111111B
4
5 >> (al)=00001101B

2、or指令

只要2个事件中有1个是真即为真,即1||1==>1,1||0==>1,0||0==>0;

用处:假如想把一个数的第7位变成1,让它和10000000B执行或操作就好了

mov al,01101101B    ; 8位数据

or al,10000000B

>> (al)=11101101B

ASCII码

大小写转换

由上图可以得知大写字母的ASCII码比小写字母的ASCII码小32(20H),也就是说大写字母和小写只有第5位不同(大写:0,小写:1)

大写     二进制             小写       二进制
 A         01000001          a         01100001
 B         01000010          b         01100010
 C         01000011          c         01100011
 D         01000100          d        01100100

示例:将BaSiC全部变成大写,将iNfOrMaTiOn全部变成小写。

 1 assume cs:codesg,ds:datasg
 2 datasg segment
 3     db ‘BaSiC‘            ; 0~4内存单元
 4     db ‘iNfOrMaTiOn‘    ; 5~15内存单元
 5 datasg ends
 6
 7 codesg segment
 8  start: mov ax,datasg
 9         mov ds,ax
10         mov bx,0
11         mov cx,5        ; 循环5次
12
13         ; 将BaSiC全部变成大写
14       s:mov al,[bx]          ; 获取相应内存单元的值,赋给al低位寄存器
15         add al,11011111B; 将第5位变成0
16         mov [bx],al        ; 将修改后的放回之前的内存单元
17         inc bx            ; bx自增1
18         loop s
19
20         mov bx,5
21         mov cx,11
22         ; 将iNfOrMaTiOn全部变成小写
23      s0:mov al,[bx]
24         or al,00100000B ; 将第5位变成0
25         mov [bx],al
26         inc bx
27         loop s0
28
29 codesg ends
30 end start

[bx+idata]

我们可以用[bx]的方式来指明一个内存单元, 我们还可以用一种更为灵活的方式来指明内存单元:
[bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上idata)。

示例:使用[bx+idata],将BaSiC全变小写,将MinIX全变大写

 1 assume cs:codesg,ds:datasg
 2 datasg segment
 3     db ‘BaSiC‘        ; 内存单元0-4
 4     db ‘MinIX‘        ; 内存单元5-9
 5 datasg ends
 6
 7 codesg segment
 8  start: mov ax,datasg
 9         mov ds,ax
10
11         mov bx,0
12         mov cx,5
13
14       s:mov al,[bx]
15         or al,00100000B        ; 或操作,全变成小写
16         mov [bx],al
17
18         mov bl,[bx+5]
19         and al,11011111B    ; 与操作,全变成大写
20         mov [bx+5],al
21         inc bx
22         loop s
23
24         mov ax,4c00H
25         int 21H
26
27 codesg ends
28 end start

SI和DI寄存器

si和di寄存器和ds寄存器的作用一样,都是用来表示内存的偏移地址的。只是SI和DI不能够分成两个8 位寄存器来使用。

我们还可以这样使用它们:[bx+si],[bx+di]和[bx+si+idata],[bx+di+idata],其实和[dx+idata]一样

示例:*****

将datasg段中每个单词改为大写字母

我们很容易就会想到以下代码,因为在第2层循环中修改了cx。等它们跳出第二层循环时cx=0,第一层循环会执行cx=cx-1 ==>-1(FFFF),从而进入死循环

 1 assume cs:codesg,ds:datasg
 2 datasg segment
 3    db ‘ibm            ‘        ; 16个字节 0-15
 4    db ‘dec            ‘        ; 16-31
 5    db ‘dos            ‘        ; 32-47
 6    db ‘vax            ‘        ; 48-63
 7 datasg ends
 8
 9 codesg segment
10  start: ; 因为要将每行的每个单词改为大写,所以我们需要写两层循环
11         mov ax,datasg
12         mov ds,ax
13         mov bx
14         mov cx,4
15       s:mov cx,3
16         mov so,0    ; 这个要写在外面
17      s0:
18         mov al,[bx+si]
19         add al,11011111B
20         mov [bx+si],al
21         inc si        ; 如果是将bx+1的话,就会1,2,3,13,14,15,...这样,所以我们要用si/di寄存器
22         loop s0
23
24         add bx,16
25         loop s
26
27         mov ax,4c00H
28         int 21H
29
30 codesg ends
31 end start

我们可以采用把cx的值放进其他寄存器中,但寄存器是有限的,当程序过大就不够用了

 1 assume cs:codesg,ds:datasg
 2 datasg segment
 3    db ‘ibm            ‘        ; 16个字节 0-15
 4    db ‘dec            ‘        ; 16-31
 5    db ‘dos            ‘        ; 32-47
 6    db ‘vax            ‘        ; 48-63
 7 datasg ends
 8
 9 codesg segment
10  start:
11         mov ax,datasg
12         mov ds,ax
13         mov bx
14         mov cx,4
15       s:mov cx,3
16         mov dx,cx    ;;;;;; 用其他寄存器保存一下
17
18      s0:mov si,0
19         mov al,[bx+si]
20         add al,11011111B
21         mov [bx+si],al
22         inc si
23         loop s0
24
25         add bx,16
26         mov cx,dx    ;;;;; 将cx取出
27         loop s
28
29         mov ax,4c00H
30         int 21H
31
32 codesg ends
33 end start

然后我们可以把他放进内存中,内存是可以随便用的啊,但当循环多的时候,你需要把所以内存位置都记住。这很不方便

 1 assume cs:codesg,ds:datasg
 2 datasg segment
 3    db ‘ibm            ‘        ; 16个字节 0-15
 4    db ‘dec            ‘        ; 16-31
 5    db ‘dos            ‘        ; 32-47
 6    db ‘vax            ‘        ; 48-63
 7    dw  0        ;;;;; 定义一个字来保存cx的值(64)
 8 datasg ends
 9
10 codesg segment
11  start:
12         mov ax,datasg
13         mov ds,ax
14         mov bx,0
15         mov cx,4
16       s:mov cx,3
17         mov [64],cx    ;;;;;; 放进字单元中保存一下
18         mov si,0
19      s0:
20         mov al,[bx+si]
21         add al,11011111B
22         mov [bx+si],al
23         inc si
24         loop s0
25
26         add bx,16
27         mov cx,[64]    ;;;;; 将cx取出
28         loop s
29
30         mov ax,4c00H
31         int 21H
32
33 codesg ends
34 end start

所以我们要使用栈的方式来进行两层循环的嵌套

这样做的好处是:多层循环嵌套的话,每一层往里面push一个值,等它出来的时候pop的值就是那个,我们只需要管理一个栈就好了,不用管其他的。

 1 assume cs:codesg,ds:datasg,ss:stacksg
 2 datasg segment
 3    db ‘ibm            ‘        ; 16个字节 0-15
 4    db ‘dec            ‘        ; 16-31
 5    db ‘dos            ‘        ; 32-47
 6    db ‘vax            ‘        ; 48-63
 7 datasg ends
 8
 9 stacksg segment
10     dw 0,0,0,0,0,0,0,0        ;;;;; 定义一个栈段
11
12 codesg segment
13  start:
14         mov ax,datasg
15         mov ds,ax
16         mov ax,stacksg        ;;;;; 保存栈段的位置
17         mov ss,ax            ;;;;; 赋值给ss
18         mov sp,16            ;;;;; 指向栈顶
19         mov bx,0
20         mov cx,4
21       s:mov cx,3
22         push cx    ;;;;;; 入栈
23         mov si,0
24      s0:
25         mov al,[bx+si]
26         add al,11011111B
27         mov [bx+si],al
28         inc si
29         loop s0
30
31         add bx,16
32         pop cx     ;;;;; 出栈
33         loop s
34
35         mov ax,4c00H
36         int 21H
37
38 codesg ends
39 end start
时间: 2024-11-05 06:31:37

汇编语言——更灵活的定位内存地址的方法的相关文章

更灵活的定位内存地址的方法(学习汇编)

1.and指令:逻辑与指令,按位进行与运算.与1不变,与0变0,可将对象相应位设为0. 2.or指令:逻辑或指令,按为进行或运算.或1变1,或0变0,可将对象位设为1. 3.[BX+idata]的几种表现形式: mov ax,[200+bx] mov ax,200[bx] mov ax,[bx].200 4.SI和DI是8086CPU中和Bx功能相似的寄存器,只是不能分成两个8位的寄存器来用. 5.[BX+SI]进行内存地址定位的几种形式: mov ax,[bx][si] mov ax,[bx+

汇编语言学习第七章-更灵活的定位内存地址的方法

本博文系列参考自<<汇编语言>>第三版,作者:王爽 前面已经通过类似[0]和[bx]的方法进行了内存定位了.本章将涉及更多内存地址定位和编程的方法. 7.1 and 和 or 指令 (1) and指令,逻辑按位与指令 例如: mov al,01100011B and al,00111011B 执行后 al=00100011B and指令可以用来将某个数的位置为零. 比如我们要将al的第二位置为零,则: and al,11111101B 依次类推. (2) or指令,逻辑按位或指令

《汇编语言》总结04 —— 更灵活的定位内存地址的方法

(一)and和or指令 and指令:逻辑与指令,按位进行与运算 mov al,01100011B and al,00111011B 执行后,al=00100011B 作用:通过该指令可将操作对象的相应位设为0,其他位不变. or指令:逻辑或指令,按位进行或运算 mov al,01100011B or al,00111011B 执行后:al=011111011B 作用:通过该指令可将操作对象的相应位设为1,其他位不变. (二)关于ASCII码 世界上有很多编码方案,有一种方案叫做ASCII编码,是

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

一.and和or指令 ①and指令:逻辑与指令,按位进行与运算.(仅在1与1时结果中为1) eg:mov al,01100011B and al,00111011B 结果:al=00100011B 作用:通过该指令可以将操作对象的相应位设为0,其他位不变. ②or指令:逻辑或指令,按位进行或运算.(仅在0或0时为0) eg:mov  al,01100011B or   al,00111011B 结果:al=01111011B 作用:通过该指令可以将操作对象的相应位设为1,其他位不变. 注意:(1

第七章 更灵活的定位内存地址的方法 知识梳理

and和or指令 and逻辑与指令 作用:通过该指令可以将操作对象的相应位设为0,其他位不变 or 逻辑或指令 作用:通过该指令可以将操作对象的相应位设为1,其他位不变 [bx+idata]  [bx+si] [bx+di] si,di 在8086CPU中和BX功能相近的寄存器 si和di不能分成两个8位寄存器来使用! 等效写法 两个变量表示地址:[bx+si]  ↔  [si+bx], [bx][si], [si][bx] 一个变量一个常量表示地址:[bx+idata]  ↔  [bx]ida

汇编语言:第七章 更灵活定位内存地址的方法

7.1 and 和 or 指令 二进制的and or 可以将某位归0或置1 7.2 关于ASCII码 7.3 以字符形式给出数据 data segment db 'unIX'                    //相当于db 75H,6EH,49H,58H db 'foRK' //相当于db 66H,6FH,52H,4BH data ends mov al,'a'   //相当于mov al,61H 7.4 大小写转换问题 db 'BaSiC' db 'iNfOrMaTiOn' 如何将第一个

汇编语言学习笔记(7)——更灵活地定位内存

1.and指令 逻辑与指令,按位进行与运算,例如: mov al,01100011B and al,00111011B 计算后的al结果为:00100011B 计算过程: 0 1 1 0 0 0 1 1 B 0 0 1 1 1 0 1 1 B ---------------------------- 0 0 1 0 0 0 1 1 B 可以看出,逻辑与运算两个二进制的思路是,设1为真,0为假,则按位对应两个数,同一位置上下两个值同为真则结果为真(1),同为假则结果为假(0),一真一假结果为假(0

重新定位svn地址的方法(windows和linux),svn switch(sw)的帮助信息

今天公司的路由器出现问题,服务器的IP地址也跟着变了,但是原来的svn已经设置好了,现在需要更换地址 查询原地址的方法: [ruby] view plain copy print? root@jack-desktop:codes# svn info 路径: . URL: http://192.168.1.58/repos 版本库根: http://192.168.1.58/repos/linux_monitor 版本库 UUID: 81fe7417-a8b1-40d6-90b8-66197304

解决新装 Win 7 SP1 系统更新高CPU及内存占用率方法

最近重新安装了win7 sp1,系统更新始终无法工作,开始怀疑是驱动安装出现问题.但反复安装新旧驱动也解决不了问题,出现update服务cpu(Svchost.exe)占用居高不下的情况.网上也找了不少办法,什么重启服务,修复Windows更新服务等一系列不靠谱的方法,都是无济于事.几乎翻遍了整个互联网终于功夫不负有心人,找到了最终解决方法,就是需要提前安装一个补丁,但经过反复实验,事实证明需要安装两个补丁. 1.KB3102810 该补丁可以解决更新时CPU满载及大内存占用的情况 2.KB94