提示:参考书本p161-例5.1
思路我们在将进制转换的时候是需要倒着处理的,BX是两个字节也就是16位,假如是1101011000111010,那么可以分成四位四位来看,也就是[1101][0110][0011][1010]对应的是D63A,我们倒着来就需要先处理前四位,那么我们将其左移四位(通过rol bx,cl指令)变成:
[0110][0011][1010][1101]
此时al存放的是低8位也就是[1010][1101],因为我们要处理后面四位,所以将al中的前4位置0,也就是用and al 0fh,这样让al与[0000][1111]取and,就可以达到。接着输出并且ch-1,继续左移,直到循环了四次,此时ch=0结束(jnz指令)
还需要注意的是:al需要加上30h(+48)变成ASCII码然后与3ah(也就是(‘9’+1),如果小于那么说明就是数字,如果大于的话那么我们需要输出字符,还得加上7h,然后再输出
prognam segment ;代码段 main proc far assume cs:prognam start: push ds sub ax,ax push ax ;保留原数据 mov ch,4 ;设置循环次数 mov bx,34827 ;加入数据测试 rotate: mov cl,4 rol bx,cl ;bx 左移4位,先左移四位,可以达到从前往后处理 mov al,bl ;将bl给al bl有8位 and al,0fh ;将这8位的前4位置0 add al,30h ;+30H +48 cmp al,3ah ;与'9'+1比较 jl printit ;小于0跳转printit add al,7h ;+7再跳转printit printit: mov dl,al mov ah,2 int 21h ;以上三行是输出 dec ch jnz rotate ;jnz不为0则转移 ret ;不然return掉 main endp prognam ends end实验二 求ARRAY数组中最大值,并且以十六进制输出
提示:代码段、流程图如下
data segment array dw 4,6fffh,34,100,5ah,6b3h,1,0f234h,6,10 n dw 10 max dw ? data ends思路
我一开始的思路是跟C++一样,用max来存最大值,实际上在汇编中需要用到寄存器来存,所以我们用ax来存第一个值,然后再一次扫一遍其他的,维护ax一直存的是最大的,如图所示。
我们可以用lea bx,array来将bx存array第一个的偏移地址
也可以用到其他寻址方式,首先将bx值0(mov bx,0),然后用类似数组的下标来 *** 作,mov ax,array[bx]
因为array里面是dw,也就是双字节,所以我们bx每次移动是2位,也就是add bx,2,然后对ax和当前array的数进行比较,注意这里
我们思路是如果小于,那么就重置ax,在汇编中我选择用类似C++中的continue的做法,如果jg(大于)那么就跳转到skip执行循环 *** 作,那么相反,如果小于的话那么就执行重置ax *** 作
;循环 s: add bx,2 cmp ax,[bx] ;比较ax 和当前 jg skip ;greater mov ax,[bx] skip: loop s ;循环结束 mov max,ax
最后转换成16进制还是用到第一个程序的代码
代码data segment array dw 4,6fffh,34,100,5ah,6b3h,1,0f234h,6,10 n dw 10 max dw ? data ends ;-----------------data--------------- code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov ax,n dec ax mov cx,ax ;cx=9 循环9次 lea bx,array ;将array的首地址给bx mov ax,[bx] ;ax相当于我们所说的哨兵 ;循环 s: add bx,2 cmp ax,[bx] ;比较ax 和当前 jg skip ;greater 如果大于那么就是跳到skip进行循环 mov ax,[bx] ;如果小于的话那么就重置ax skip: loop s ;循环结束 mov max,ax mov bx,ax mov ax,0 mov ch,4 ;开始转换 rotate: mov cl,4 rol bx,cl ;bx 左移4位 mov al,bl ;将bl给al bl有8位 and al,0fh ;将这8位的前4位置0 add al,30h ;+30H +48 cmp al,3ah ;与'9'+1比较 jl printit ;小于0跳转printit add al,7h ;+7再跳转printit printit: mov dl,al mov ah,2 int 21h ;以上三行是输出 dec ch jnz rotate ;jnz不为0则转移 ;不然return掉 mov ax,4c00h int 21h code ends end start实验三 将长度为count的str字符串按照从小到大的顺序排序并输出
参考:p172 例5.7
代码段给出如下:
data segment str db 'qwertyuiopasdfghjklzxcvbnm',0dh,0ah,'$' count dw 26 data ends思路
大致思路就是我们所学的冒泡排序,这里写一下易错的思路
1.这里代码段str是db,也就是单字节(8位),所以bx再增加的时候不再是上一个程序+2,而是add bx,1与[bx+1],比较的时候不是ax了而是al
2.我们循环只能将cx--,而内层循环的时候会将外层循环的值也改变,所以我们需要在进行内层循环的时候将cx先保存起来,可以用mov di,cx先将cx的值放入di中,然后内存循环完毕之后cx=0,这时候将di中的值再给cx,这样内层循环完毕之后cx没有改变,然后进行的是loop中cx--的 *** 作
3.xchg用法,交换,并且循环里面的al相当于我们交换里面的tmp
4.字符串输出,根据实验一里面的
mov ah,09h lea dx,str int 21h mov ax,4c00h int 21h代码
data segment str db 'qwertyuiopasdfghjklzxcvbnm',0dh,0ah,'$' count dw 26 data ends ;-------------------------data code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov cx,count dec cx lea bx,str ;bx存str开始的偏移地址 loop1: mov di,cx lea bx,str loop2: mov al,[bx] cmp al,[bx+1] jle continue ;小于无需交换 xchg al,[bx+1] mov [bx],al continue: add bx,1 loop loop2 mov cx,di loop loop1 mov ah,09h lea dx,str int 21h mov ax,4c00h int 21h code ends ;------------------------------------------------------- end start
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)