2021-09-16 10:16:18

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

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

[toc]

前面用过直接寻址 [0]和间接寻址[bx]

and 和 or指令

就是按位与 按位或。

and ax, 0111h (ax) = (ax) and 0111h

or ax, 0111h (ax) = (ax) or 0111h

关于ASCII码

我记得以前有个同事说过一个问题:

声明编码为utf8 和 gbk, 你怎么识别呢?

譬如美国人说我说的英语。。中国人说我说的中国话。两个人互相听不懂对方的话,有啥意义?

这里他就是没理解ASCII码。 在所有编码中ASCII码都是一样的,可以说是通用语。所以声明编码是有意义的。

这里简单拓展下utf8编码。

utf8是一种变成字节编码方式。有的字符用1个字节表示,有的字符用2个字节表示,有的字节用3个字节表示。那么你怎么去解析呢?

有规则:

1字节 以0开头。。这里也就是ASCII码。。。所以说utf8中的ascii码 表示 和ascii码是一样的。

2字节 110xxx 10xxx

3字节 1110xxx 10xxx 10xxx

当按这个规则解析异常时,就表示解析失败。譬如解析时遇到111011011 10xxx 1110xxx 这就有问题了,第三个字节应该是10开头才对。

这种不能识别的字节,会被转成三个字节{11101111,10111111,10111101}, 也就是239,191,189

以字符形式给出的数据

在汇编程序中可以用’…'的方式指明数据是以字符的形式提供的,这样编译器会把他们转成相应的ASCII码。

assume cs:code, ds:data
data segment
  db 'unIX'; db = define byte, 相当于 db 75H, 6EH, 49H, 58H 谁会去记具体的ASCII码,难记也难写。
  db 'foRk'
data ends

code segment
start: mov al, 'a'
			 mov bl, 'b'
			 mov ax, 4c00h
			 int 21h
cod ends

end start

大小写转换的问题

就是利用一个规律。

字母 and 1101111B = 大写字母

字母 or 00100000B = 小写字母

[bx+idata]

除了 mov ax, [0] mov ax,[bx]这样常量,变量的形式,还支持常量+变量的方式。

mov ax,[bx+200]表示 (ax) =( (ds)*16+(bx)+200)

其他形式还有:

mov ax, [200+bx]

mov ax, 200[bx]

mov ax, [bx].200

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

把大小写转换程序 改用数组实现

assume cs:codesg, ds:datasg
datasg segment
	db 'BaSiC'
	db 'MinIX'
datasg ends

codesg segment
start:mov ax,datasg
			mov ds,ax
			mov bx,0
			mov cx,5
		s:mov al,[bx] ; 一个字符只占一个字节,所以得用al
		  add al, 11011111b; 这里是转大写
		  mov [bx], al ; 转换完,放回去
		  mov al,[5+bx]
		  or al, 00100000b
		  mov [bx],al
		  inc bx
		  loop s
		  
		  mov ax, 4c00h
		  int 21h
codesg ends

end start

SI和DI

si和di是8086CPU中 和 bx功能相近的寄存器,不过他不能分成两个 8位寄存器来使用。

[bx+si]和[bx+di]

就是2个变量组合了。

之前有常量,变量,常量+变量。这就是变量+变量。

mov ax, [bx+si] (ax) =( (ds)*16 + (bx)+(si))

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

内存寻址,变量+变量+常量。

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

寻址总结:

  1. [idata], 常量,直接寻址。
  2. [bx], 变量,间接寻址。
  3. [bx+idata] 变量+常量
  4. [bx+si] 2个变量
  5. [bx+si+idata] 2个变量+常量

一般来说,在需要暂存数据的时候,我们都应该使用栈。

本文链接:http://blog.go2live.cn/post/assemble-7.html

-- EOF --