【汇编语言】【笔记】更灵活的定位内存地址的方法

更加灵活的定位内存地址的方法


andor命令

  • and指令:逻辑与指令,按位进行与运算
    Ex:
    mov al,01100011B and al,00111011B
    (al) = 00100011B
    上第一位为0,下第一为0,0和0做与运算得0
    上第三位为1,下第三位为1,1和1做与运算得1
    上第四位为1,下第四位为0,1和0做与运算得0
    8位全部运算后得到新的数据
  • or指令:逻辑或指令,按位进行或运算
    运算过程与and指令运算过程类似

以字符形式给出的数据

'......'的方式给出的数据是以字符的形式给出的,编译器将它们转化为ASCII码

assume cs:code, 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表示定义字节型数据,一个字节占用一个内存单元,偏移量加一
db 'unIX'相当于db 75H,6EH,49H,58H,字符与ASCII码相对应

大小写转换的问题

问题:将data中的第一个字符转化为大写,第二个字符转化为小写
分析:

  • 小写字母的ASCII码比大写字母的ASCII码大20H,即小写字母-20H = 大写字母,大写字母转化为小写字母则相反
    但我们尚没有办法使用比较大小相关的指令,所以要另辟蹊径
  • 从ASCII码的二进制的形式来看,大写字母与小写字母只有第六位(从右往左)不同
    大写字母第六位为0,小写字母第六位为1
    即新的方法,只要将一个字母的二进制形式的第六位变为0,它将变成大写,小写同理
    使用andor指令可以完成这样的运算
完整程序
assume	cs:code,ds:data
data	segment
	db 'BaSiC'
	db 'iNfOrMaTiOn'
data ends'

code segment
start:	mov ax,data
		mov bx,0
		mov cx,5
	s:	mov al,[bx]
		and al,11011111B
		mov [bx],al
		inc bx
		loop s
		mov bx,5
		mov cx,11
	s0:	mov al,[bx]
		or al,00100000B
		mov [bx],al
		inc bx
		loop s0
		
		mov ax,4c00h
		int 21h
code ends
end start

[bx+idata]

更加灵活的指明内存单元的方式:[bx+idata]
偏移地址为(bx) + idata

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

对于上个问题,两个字符串,一个字符串的起始地址为0,长度为5,另一个字符串的起始地址即为5
可以用[0+bx][5+bx]来标识两个字符串的第bx个字符
0和5给了两个字符串的起始偏移地址,bx给出了从起始偏移地址开始的相对地址

对上个程序进行简化
	mov	ax,data
	mov	ds,ax
	mov	bx,0

	mov	cx,5
s:	mov al,0[bx]	;[idata+bx]可表示为idata[bx]
	and al,11011111b
	mov 0[bx],al
	mov al,5[bx]
	or al,00100000b
	mov 5[bx],al
	inc bx
	loop s

[bx+idata]的方式为高级语言实现数组提供了便利机制

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

SI和DI是8086CPU中和bx功能相近的寄存器
但SI和DI不能够分成两个8位寄存器使用
[bx+si+idata]表示一个内存单元
它的偏移地址是(bx)+(si)+idata

不同的寻址方式的灵活运用

问题1:将data段中每个单词的头一个字母改成大写字母

assume	cs:code,ds:data
data	segment
	db '1. file         '		;将每个单词定义到一串固定长度的空间内方便地址增加,即换行
	db '2. edit         '
	db '3. search       '
	db '4. view         '
	db '5. options      '
	db '6. help         '
data ends

code  segment
start:mov ax,data	;将data段地址送入ax中国
	  mov ds,ax	;经过ax中转,data 段地址被送入ds中
	  mov bx,0		;bx即我们即将要访问内存单元要用的偏移地址,初始化为0,此时定位到第一个单词所在的空间
	  
	  mov cx,6		;6个单词循环6次
s:	  mov al,[bx+3]	;bx=0时,bx+3得到3,即偏移量为4,即第一个单词的首字母送入al寄存器中
	  and al,11011111b	;将第五位变为0即可将字母变为大写
	  mov [bx+3],al	;将变为大写字母的字符送入字母原来所在的内存单元
	  add bx,16	;偏移地址加16即定位到下个单词所在的空间
	  loop s		;执行下一次循环
code ends
end start
	

内存单元单元实际上线性顺序排列的,第一个字符占用了16个内存空间即0到15
0到16内第一个单词所在的内存单元为第四个单元即为3,相对于0的偏移量为3
第二个字符在第一个字符的后面,所用的空间即为16到31
而第二个单词所在的位置为19,相对于16的偏移量为3
综上所述,即单词的首字母相对于这个字符的起始地址的偏移量为3
每个字符占用了16个内存单元,所以每个字符的起始地址相差16,即bx迭加16

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值