1.数据传送: 问题描述:
设在DS=3000H,偏移地址为0100H的内存中顺序存放着100个字节的数据。要求传送到以2000H为起始偏移地址的区域。 代码:
利用寄存器间接寻址来寻找操作数可以编程如下: mov ax,3000h
mov ds,ax ;建立数据段 mov si, 0100h ;建立源数据指针 mov di,2000h ;建立目的地指针 mov cx,100 ;设置计数器 nt: mov al,[si] ;取数 mov [di],al ;送数 inc si ;调整指针 inc di
dec cx ;计数器减1
jne nt ;CX-1≠0转 nt 标号 另一种方法:
提示:
若将倒数第2、3行用 REP MOVSB代替,则可进一步简化。
MOV AX,3000H MOV DS,AX MOV ES,AX MOV SI,0100H MOV DI,0200H MOV CX,100
CLD NT:MOVSB LOOP NT INT 20H
2.多字节的加法: 问题描述:
有两个4字节的无符号数相加,这两个数分别放在2000H和3000H开始的存储单元中,低位在前,高位在后。运算后,得到的和放在2000H开始的内存单元中。 代码:
MOV SI,2000H ;取第一个数的首地址 MOV AX,[SI] ;将第一个数的低16位取到AX MOV DI,3000H ;取第二个数的首地址 ADD AX,[DI] ;两个数的低16位相加。
MOV [SI],AX ;低16位相加的结果送到2000H和2001H单元 MOV AX,[SI+2] ;取第一个数的高16位送到AX中 ADC AX,[DI+2] ;两个数的高16位连同CF相加
MOV [SI+2],AX ;高16位相加的结果送到2002H,2003H单元。
3.多字节组合BCD码十进制加法 问题描述:
设第一个数据在1000H开始的8个内存单元中,第二个数据在2000H开始的8个内存单元中,要求相加之后将结果放在2000H开始的内存区域。 代码:
mov si,1000h ;SI指向第一个数据 mov di,2000h ;DI指向第二个数据 mov cx,8 ;共有8字节长 c1c ;清除进位标志
l1: mov a1,[si] ;取第一个数据的1个字节 adc a1,[di] ;加上第二个数据的相应字节 daa ;对相加结果进行十进制调整 mov [di],a1 ;存到指定的内存区域 inc si ;指向下一个字节 inc di ;指向下一个字节 dec cx ;计数器减1
jnz l1 ;如未算完,则继续 int 20h ;返回DOS
4.多字节的移位
问题描述:使BX所指的四个单元中的四字节数左移1位, 代码:SAL WORD PTR [BX+0],l RCL WORD PTR [BX+2],1
5.ASCII码转换为BCD码
问题描述:设键盘输入的100个十进制数的ASCII码已在首地址DS为3000H,偏移量为0100H的内存区域中,要求把它们转换为组合型BCD码,高地址的放在高半字节。存入偏移地址为0200H的区域中。
分析:算法是这样的:先将较低字节的32H转换为02H,再将较高字节的34H转变为40H,然后将其与02H按位相或成为42H。循环50次完成50个字节的组合BCD码的转换。 代码:
MOV AX,3000H MOV DS,AX MOV SI,0100H MOV DI,0200H MOV CX,0032H NEXT:MOV AL,[SI] INC SI
AND AL,0FH MOV BL,AL MOV AL,[SI] INC SI PUSH CX MOV CL,4 SHL AL,CL POP CX ADD AL,BL MOV [DI],AL INC DI LOOP NEXT INT 20H
6.比较两个字符串
问题描述:假设两个字符串分别放在DS段(设ES=DS)的str1和str2区域,其长度分别为L1和L2,比较这两个字符串是否相等。若相等,则置M1单元内容为FFH,否则为00H。 代码:
提示:
前缀REPZ和REPE表示,当作比较的两字节(或字)相等时继续往下比较直至出现不等,或者CX减为0为止。
重复前缀使用前必须对CX置重复次数。每比较一次,CX-1→CX (字比较CX-1→CX)。CX=0表示两个字符串所有字节都比较过了,这时结束比较。
前缀REPNE和REPNZ则表示字节(字)不等时继续往下比较。
LEA SI,STR1
LEA DI,STR2 MOV CX,L1 CMP CX,L2 JNE UNEQ CLD
REPZ CMPSB JNE UNEQ MOV AL,0FFH JMP EXIT1 UNEQ:MOV AL,00H EXIT1:MOV M1,AL INT 20H
7.有条件的数据传送
问题描述:将从BLOCK1单元开始的100个字节传送到BLOCK2单元开始的区域中,两区域的相对位置不确定。数据传送过程中遇0DH(回车符)则结束传送。假设DS=ES,即BLOCK1和BLOCK2同在一个数据段,并且位置不定(BLOCK1值可以大于、小于或等于BLOCK2)。
分析:由于该题要求有条件传送,使用MOVSB指令不如LODSB和STOSB方便。又因源数据区和目标数据区有可能重叠,所以应区分两种情况分别用地址增量和地址减量的方式来传送。若源地址大于目的地地址,则应用地址增量方式从首地址开始传送,反之,则应用地址减量方式从末地址开始传送。 代码:
LEA SI,BLOCK1 LEA DI,BLOCK2 MOV CX,100 CMP SI,DI JE DONE JA DFO
STD ADD SI,99 ADD DI,99 JMP TRAN DFO:CLD TRAN:LODSB CMP AL,0DH JE DONE STOSB LOOP TRAN DONE:INT 20H
8.确定字符串的长度
问题描述:
在STRING为始地址的字符串中搜索字符串结束符“$”,并将字符串的长度(不包括“$”)放入STRLN单元中;如果连续100个字节单元之中无“$”符则在STRLN单元中填入0FFH。
提示:目标串搜索指令 SCASB 和 SCASW将AL(或AX)与ES:DI所寻址的字节(或字)内容进行比较而不改变其值;只影响标志位SF、ZF、PF、OF、CF、AF,并且修改DI指针使指向目标串中下一个元素。 代码:
LEA DI,STRING MOV AL,?$? MOV CX,100 CLD
REPNE SCANSB
JZ DONE1 MOV AL,0FFH JMP DONE2
DONE1: MOV BX,100 SUB BX,CX DEC BL MOV AL,BL DONE2: MOV STRLN,AL INT 20H
另一方法:
LEA DI,STRING MOV AL,?$? MOV CX,100 DEC DI L1: INC DI CMP AL,[DI] LOOPNE L1 JZ DONE1 MOV AL,0FFH JMP DONE2 DONE1: MOV BX,100 SUB BX,CX DEC BL MOV AL,BL DONE2: MOV STRLN,AL
INT 20H
9.求符号数的最大值 问题描述:
设数据区1000H开始的区域中存放着50个字节的符号数。要求找出其中最大的一个数并存到0FFFH单元。 代码:
MOV BX,1000H MOV AL,[ BX ] MOV CX,31H L1: INC BX
CMP AL,[ BX ] JGE L2
MOV AL,[ BX ] L2: DEC CX JNE L1
MOV BX,0FFFH MOV [ BX ],AL INT 20H
注:如果是无符号数则把JGE L2换为JAE L2。
10.两个32位无符号数乘法
问题描述:32位乘法需要做4次16位乘法,每次都要将部分积相加来实现,相加时则要注意位数对齐。我们用连续的四个字单元来存放乘积,各部分积应加到适当单元。 分析:
data segment
num1 dw 8000h,8000h num2 dw 8008h,8000h mut dw 4 dup (0) data ends
stack segment stack ?stack? db 100 dup (?s?) stack ends
code segment para ?code? assume cs: code, ds: data, ss: stack proc far push ds xor ax,ax push ax mov ax,data mov ds,ax lea bx,num1
mov ax,[bx] ; b→ax
mov si,[bx+4] ; d→si
mov di,[bx+6] ; c→di mul si ; b*d
mov [bx+8],ax ;部分积1存于积单元中。 mov [bx+10],dx
mov ax,[bx+2] ; a→ax mul si ; a*d add [bx+10],ax adc [bx+12],dx ; 带进位加入积2单元中 mov ax,[bx] ; b→ax mul di ; b*c add [bx+10],ax ; b*c 加入积单元 adc [bx+12],dx ; 带进位加至部分积3 adc word ptr [bx+14],0 ; 进位加至部分积4
mov ax,[bx+2] ; a→ax mul di ; a*c add [bx+12],ax adc [bx+14],dx ret
sta endp
code end end sta 11.
data segment x dw 12 y dw ? data ends
stack segment stack ?stack? db 100 dup (?s?) stack ends
code segment para ?code?
assume cs:code, ds:data, ss:stack sign proc far push ds xor ax, ax push ax mov ax, data mov ds, ax mov ax, x
and ax, ax ; 建立标志 jz zero jns plus
mov bx, 0ffffh jmp done zero: mov bx, 0 jmp done plus: mov bx, 1 done: mov y, bx ret sign endp code ends end sign
12.大散转 问题描述:
根据BUFFER单元的值,转到相应的子程序。子程序的入口地址存放在转移表BRTAB中。若BUFFER内容等于n,则转到第n个子程序(n从1~256,0代表256)。 代码:
data segment buffer db 3
brtab dw 0000h, 3000h dw 0100h, 3050h dw 0000h, 3090h dw 0100h, 4050h dw 0000h, 6000h data ends
stack segment stack ?stack? db 100 dup (?s?)
stack ends
code segment para ?code?
assume cs:code, ds:data, ss:stack brch proc far push ds xor ax, ax push ax mov ax, data mov ds, ax lea bx, brtab mov al, buffer dec al moav ah, 0 shl ax, 1 ; AL*2 shl ax, 1 ; AL*4 add bx, ax jmp dword ptr [bx] ret brch endp code ends end brch
13.数组求和 问题描述:
假设有一数组求和子程序SUM,试用这个子程序分别求出ARY1和ARY2两个数组的和,结果分别存入SUM1和SUM2字单元中。 代码:
data segment
aryl db 03h, 07h, 50h, 06h, 23h, 45h, 0f6h, 0dfh len1 equ $-ary1 sum1 dw ?
ary2 db 33h, 44h, 55h, 12h, 78h, 89h, 0feh, 0cdh len2 equ $-ary2 sum2 dw ? data ends
stack segment stack ?stack? db 100 dup (?s?) stack ends
code segment para ?code?
assume cs:codc,ds:data,ss:stack sta proc far push ds xor ax,ax push ax mov ax,data mov ds,ax mov ax,len1 push ax lea ax,ary1 push ax call sum mov ax,len2 push ax lea ax,ary2
push ax call sum ret sta endp sum proc push bp mov bp,sp push ax push bx push cx pushf
mov cx,[bp+6] ; get array lenth mov bx,[bp+4] ; get offset address xor ax,ax ; sum=0 add1: add al,[bx] adc ah,0 inc bx loop add1 mov [bx],ax popf pop cx pop bx pop ax pop bp ret 4 sum endp code ends end sta
14.阶乘 问题描述:
确定变量NUMB的阶乘,把结果存入变量FNUMB。变量NUMB的值大于0且小于8。 代码:
data segment num db 3 nj dw ? data ends
stack segment stack ?stack? db 200 dup(?s?) stack ends
code segment para ?code?
assume cs:code,ds:data,ss:stack sta proc far push ds xor ax,ax push ax mov ax,data mov ds,ax push cx mov ah,0 mov a1,num call factor x1: mov nj,ax
pop cx ret sta endp
factor proc push ax sub ax,1 jne fcon pop ax jmp retun fcon: call factor x2: pop cx mul cl Retun: ret factor endp code ends end sta
14.16进制数转换为ASCII码 CHANGE MACRO LOCAL P1
相关推荐: