学汇编,记笔记(六)——定位内存地址_存储字符串_大小写转换_循环嵌套_二维数组问题
作者:互联网
前言
学习教材:《汇编语言(第3版)》王爽著
此笔记是书中内容+自我总结,方便查阅和复习
请支持原著
文章目录
一、位运算
汇编支持按位与、按位或运算
mov al,00111010b ;以b声明二进制
and al,11011101b ;按位与
or al,11011101b ;按位或
运算需要声明二进制,运算结果覆盖存储到第一个指明的位置
二、存储字符(串)
字符以十六进制ASCII码存储在内存单元内,一个字符占一个字节(8 bits)
使用类似以下代码声明字符(串)常量
datasg segment
db 'Hello World!' ;db字节型
datasg ends
codesg segment
mov al,'a' ;等效于mov al,61H,存储到半个ax
codesg ends
这些代码实质上使用了对应字符(串)的ASCII码
三、字符(串)的大小写转换
大小写字符的ASCII码相差32(20H,100000B),一般方法是通过判断当前的大小写类型进而采取加或减
而32是二进制第六位,因此采用位运算转换无需判断其状态直接转换,且会自动跳过无需转换的字符
字符 | 二进制 |
---|---|
A | 0100 0001 |
a | 0110 0001 |
由于真值和位运算的特性,大小写转换的运算不同,置1用按位或,置0用按位与
Ⅰ、大写转小写
大写转小写只将第六位的值置1,使用按位或
mov al,'A'
or al,00100000b
Ⅱ、小写转大写
大写转小写只将第六位的值置0,使用按位与
mov al,'a'
and al,11011111b
四、SI和DI寄存器
SI和DI类似通用寄存器,是十六位寄存器。但区别是无法拆分为两个八位寄存器
五、[bx+si+idata]定位内存地址
mov ax,[bx+si+idata]
[bx+si+idata]表示一个内存单元,它的偏移地址是(bx)+(si)+idata,总地址是((ds*16)+(bx)+(si)+idata)
还有以下写法,可均为0,其中bx和si是变量,间接定位;idata是常量,直接定位
mov ax,[bx+123+si]
mov ax,[123+bx+si]
mov ax,123[bx][si]
mov ax,[bx].123[si]
mov ax,[bx][si].123
六、尝试循环灵活定位
编程,将datasg段中的每个单词转换为小写,每个单词用空格扩展到16字节
...
datasg segment
db 'ABC '
db 'DEF '
datasg ends
...
这个问题实质是一个二维数组问题
首先需要循环两次,每次遍历三个字符,是一个循环嵌套问题。而循环次数只能存储在cx内,cx只有一个,因此会导致覆盖外层循环。
对于多重循环,在执行内层循环时,将外层循环的cx计数值存储,重新赋值循环,内层循环结束后再取出存储的cx计数值,重新赋值给cx进行外层循环
存储可以使用寄存器,但若嵌套循环过多超过总寄存器数就无法完成。因此,应采用内存来记录存储cx值。一般来说,存储数据都应该使用内存,而且是栈空间。
实现代码如下:
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
db 'ABC ' ;长16字节
db 'DEF ' ;长16字节
datasg ends
stacksg segment
dw 0,0,0,0,0,0,0,0 ;将栈段扩充到16字节的正整数倍,此处为8字(16字节)
stacksg ends
codesg segment
start:
mov ax,stacksg
mov ss,ax ;指向栈段
mov sp,10h ;指向栈底,偏移量16
mov ax,datasg
mov ds,ax ;指向数据段
mov bx,0 ;作为行号,共两个字符串
mov cx,2 ;外循环,两个字符串,共两次
s:
push cx ;外循环次数入栈
mov si,0 ;作为列号,每串共三个字符
mov cx,3 ;内循环,三个字符,共三次
s0:
mov al,0[bx][si] ;对每一行,依次取出前三个字符
or al,00100000b ;转换小写
mov 0[bx][si],al
inc si ;列号自增1,接着取出下一位字符
loop s0
add bx,10h ;行号自增16,由于每个字符串共16字节,直接偏移16到达下一行
pop cx ;外循环次数出栈,准备外循环
loop s
mov ax,4c00h
int 21h
codesg ends
end start
七、二维数组的定位
对于0[bx][si]
表示法在二维数组中的应用非常方便
以上一题为模板,bx行号si列号,至于0,由于字符串是从头开始的,因此idata值为0,若不是从头开始就需要将0改成其他值
如字符串'1.abc'
,此时进行循环就需要用3[bx][si]
指向第三位
标签:字符,mov,al,si,大小写,ax,内存地址,bx,记笔记 来源: https://blog.csdn.net/Xxy605/article/details/112708944