CC BY 4.0 (除特别声明或转载文章外)
如果这篇博客帮助到你,可以请我喝一杯咖啡~
一、and和or指令
不多说,就是与和或指令。
二、大小写转换问题
考虑一个问题,将一个字符串转换为全大写或全小写,不使用条件语句。
思路:考虑大小写的二进制。
小写字母=大写字母+20H。
故可以直接使用and和or指令。
转换为大写:使用and指令,and al,1101 1111B
转换为小写:使用or指令,or al, 0010 0000B
三、[bx+idata]的方式处理数组
[bx+idata]表示一个内存单元,偏移地址为(bx)+idata
(ax)=((ds)*16+(bx)+idata)
mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
将datasg中定义的第一个字符串转化为大写,第二个字符串转化为小写
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]
and al,11011111b
mov [bx],al
inc bx
loop s
mov bx,5
mov cx,5
s0: mov al,[bx]
or al,00100000b
mov [bx],al
inc bx
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
有了[bx+idata],我们可以改写代码为:
mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5
s: mov al,0[bx]
and al,11011111b
mov 0[bx],al
mov al,5[bx]
or al,00100000b
mov 5[bx],al
inc bx
loop s
四、si和di
si和di是8086CPU中和bx功能相似的寄存器,但是si和di不能够分成两个8位寄存器。
寻址方式:
双重循环时,loop默认的循环计数寄存器为cx,外层循环需要保存外层循环cx的值。用额外的内存,dataseg可以,但一般来说,在需要暂存数据的时候,我们都应该使用栈。
五、byte和word
byte和word用于指明指令进行的是字操作还是字节操作。
用X ptr指明操作的内存单元的长度。X为byte或word。
例如:
mov word ptr ds:[0],1
inc word ptr [bx]
inc word ptr ds:[0]
add word ptr [bx],2
mov byte ptr ds:[0],1
inc byte ptr [bx]
inc byte ptr ds:[0]
add byte ptr [bx],2
六、寻址方式的总和应用
修改数据:
按照c语言的风格:
mov ax,seg
mov ds,ax
mov bx,60h
mov word ptr [bx].0ch,38
add word ptr [bx].0eh,70
mov si,0
mov byte ptr [bx].10h[si],'A'
mov byte ptr [bx].10h[si],'X'
七、div、dd、dup指令
1. div:除法指令
除数:有8位和16位两种,在一个reg或内存单元中。
被除数:默认放在AX或DX和AX中,除数为8位,被除数则为16位,默认在AX中存放;除数为16位,被除数为32位,在DX和AX中存放,DX放高16位,AX放低16位。
结果:如果除数为8位,则AL存放商,AH存放余数。如果除数为16位,则AX存放商,DX存放余数。
div byte ptr ds:[0] ;(al) = (ax)/((ds)*16+0)的商
;(ah) = (ax)/((ds)*16+0)的余数
div word ptr es:[0] ;(ax) = [(dx)*10000H+(ax)]/((es)*16+0)的商
;(dx) = [(dx)*10000H+(ax)]/((es)*16+0)的余数
2. dd指令和dup指令
db:定义字节数据
dw:定义字型数据
dd:定义双子型数据
dup:配合上述指令表示数据的重复。
db 3 dup (0,1,2)定义了三组(0,1,2),9个字节,数据分别为0,1,2,0,1,2,0,1,2
db(dw, dd) 重复的次数 dup (重复的数据)