更灵活的定位内存地址方式
7.1 and和or命令解决大小写转换问题[bx+idata]的含义7.2 SI和DI[bx+si]和[bx+di]方式指定地址(基址+变址寻址)[bx+si+idata]和[bx+di+idata]方式指定地址不同寻址方式的灵活运用7.1 and和or命令
db ‘.......’
方式给出字符串,并将其以ASCII码的对应形式写入内存中。
在ASCII码中大小写同字母之间相差32个序号,所以可以通过与11011111b
即二进制的数据,来转换大写,或00100000b
,来转换小写。即加减32位的数值变换大小写。
解决大小写转换问题
大小写转换要通过初始化bx和循环次数,在循环中通过与或操作进行大小写转换。
代码如下:
通过两次循环实现大小写转换
assume cs:codesg,ds:datasgdatasg segmentdb 'BaSiC'db 'MinIX'datasg endscodesg segmentstart:mov ax,datasgmov ds,axmov bx,0mov cx,5s:mov al,[bx]and al,11011111bmov [bx],alinc bxloop smov bx,5mov cx,5s0:mov al,[bx]or al,00100000bmov [bx],alinc bxloop s0mov ax,4C00Hint 21Hcodesg endsend start
[bx+idata]的含义
通过单次循环[bx+idata]解决大小写转换
assume cs:codesg,ds:datasgdatasg segmentdb 'BaSiC'db 'MinIX'datasg endscodesg segmentstart:mov ax,datasgmov ds,axmov bx,0mov cx,5s:mov al,[bx]and al,11011111bmov [bx],almov al,[bx+5]or al,00100000bmov [bx+5],alinc bxloop smov ax,4C00Hint 21Hcodesg endsend start
7.2 SI和DI
SI,DI称为变址寄存器。
其特点就是不能分为两个八位寄存器来使用。一直都是16位。
[bx+si]和[bx+di]方式指定地址(基址+变址寻址)
[bx+si+idata]和[bx+di+idata]方式指定地址
不同寻址方式的灵活运用
直接寻址:通过一个常量数字来表示一个地址。
寄存器间接寻址:用一个变量[bx]表示偏移地址,存入寄存器中再传给ax。
寄存器相对寻址:通过用一个起始地址的常量[idata]来加上变量[bx]来间接表示内存单元。 基址变址寻址:用两个变量[bx+si]表示地址。 相对基址变址寻址:用
assume cs:codesg,ds:datasgdatasg segmentdb '1. file 'db '2. edit 'db '3. search 'db '4. view 'db '5. options'datasg endscodesg segmentstart:mov ax,datasgmov ds,axmov bx,0mov cx,5s:mov al,[bx+3]and al,11011111bmov [bx+3],aladd bx,16loop smov ax,4C00Hint 21Hcodesg endsend start
上面这段代码有个问题,那就是cx只有一个,到第二个循环内出来时,cx已经变为0了,那再出外层循环时,cx不是成为负数了么?我们要怎么改进呢?
我们可以通过一个多余的寄存器dx来保存。
但是如果dx已经被用了呢?寄存器可是只有14个。
相对而言我们可以用固定的内存空间保存数据,这样相较而言比占用宝贵的寄存器资源要更加划算,但是这样也有一个新问题,那就是如果当时内存空间有别的内容,可能最终会改变别的功能,造成一些后果。
再改进的话我们可以在程序运行前先定义一个栈段,把需要用到的cx的值压到栈段中,用到的时候将其弹出,回复cx。
【汇编】更灵活的定位内存地址方式——and or命令 SI DI变址寄存器 直接寻址[idata] 寄存器间接寻址[bx] 寄存器相对寻址[bx+idata] 基址变址寻址 相对基址变址寻址