设在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 标号 另一种方法:
MOV AX,3000H
提示: MOV DS,AX
若将倒数第2、3行用 REP MOVSB 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。 代码:
LEA SI,STR1 提示: LEA DI,STR2 前缀REPZ和REPE表示,当作比较的两字节 MOV CX,L1 (或字)相等时继续往下比较直至出现不等,或者 CMP CX,L2 CX减为0为止。 JNE UNEQ 重复前缀使用前必须对CX置重复次数。每比 CLD 较一次,CX-1→CX (字比较CX-1→CX)。CX REPZ CMPSB =0表示两个字符串所有字节都比较过了,这时 JNE UNEQ 结束比较。 MOV AL,0FFH 前缀REPNE和REPNZ则表示字节(字)不等 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方便。又因源数据区和目标数据区有可能重叠,所以应区分两种情况分别用地址增量和地址减量的方式来传送。若源地址大于目的地地址,则应用地址增量方式从首地址开始传送,反之,则应用地址减量方式从末地址开始传送。 代码:
STD LEA SI,BLOCK1 CMP AL,0DH
JE DONE LEA DI,BLOCK2 ADD SI,99
STOSB MOV CX,100 ADD DI,99
JMP TRAN LOOP TRAN CMP SI,DI
JE DONE DFO:CLD DONE:INT 20H JA DFO TRAN:LODSB
8.确定字符串的长度 问题描述:
在STRING为始地址的字符串中搜索字符串结束符“$”,并将字符串的长度(不包括“$”)放入STRLN单元中;如果连续100个字节单元之中无“$”符则在STRLN单元中填入0FFH。
提示:目标串搜索指令 SCASB 和 SCASW将AL(或AX)与ES:DI所寻址的字节(或字)内容进行比较而不改变其值;只影响标志位SF、ZF、PF、OF、CF、AF,并且修改DI指针使指向目标串中下一个元素。
代码:
JMP DONE2 LEA DI,STRING
MOV AL,„$‟ DONE1: MOV BX,100 MOV CX,100 SUB BX,CX CLD DEC BL REPNE SCANSB MOV AL,BL JZ DONE1 DONE2: MOV STRLN,AL
INT 20H MOV AL,0FFH
另一方法:
LEA DI,STRING MOV AL,0FFH
JMP DONE2 MOV AL,„$‟
MOV CX,100 DONE1: MOV BX,100 DEC DI SUB BX,CX L1: INC DI DEC BL CMP AL,[DI] MOV AL,BL LOOPNE L1 DONE2: MOV STRLN,AL JZ DONE1 INT 20H
9.求符号数的最大值 问题描述:
设数据区1000H开始的区域中存放着50个字节的符号数。要求找出其中最大的一个数并存到0FFFH单元。 代码:
MOV BX,1000H MOV AL,[ BX ]
L2: DEC CX MOV AL,[ BX ]
JNE L1 MOV CX,31H
L1: INC BX MOV BX,0FFFH CMP AL,[ BX ] MOV [ BX ],AL JGE L2 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存于积单元 11.
data segment x dw 12 y dw ? data ends
stack segment stack „stack‟ db 100 dup („s‟) stack ends
code segment para „code‟
中。
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
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 plus: mov bx, 1 jns plus done: mov y, bx mov bx, 0ffffh ret jmp done sign endp zero: mov bx, 0 code ends jmp done end sign
12.大散转 问题描述:
根据BUFFER单元的值,转到相应的子程序。子程序的入口地址存放在转移表BRTAB中。若BUFFER内容等于n,则转到第n个子程序(n从1~256,0代表256)。 代码:
data segment push ax buffer db 3 mov ax, data brtab dw 0000h, 3000h mov ds, ax dw 0100h, 3050h lea bx, brtab dw 0000h, 3090h mov al, buffer dw 0100h, 4050h dec al dw 0000h, 6000h moav ah, 0 data ends shl ax, 1 ; AL*2 stack segment stack „stack‟ shl ax, 1 ; AL*4 db 100 dup („s‟) add bx, ax stack ends jmp dword ptr [bx] code segment para „code‟ ret assume cs:code, ds:data, ss:stack brch endp brch proc far code ends push ds end brch xor ax, ax
13.数组求和 问题描述:
假设有一数组求和子程序SUM,试用这个子程序分别求出ARY1和ARY2两个数组的和,结果分别存入SUM1和SUM2字单元中。 代码:
data segment stack segment stack „stack‟ aryl db 03h, 07h, 50h, 06h, 23h, 45h, db 100 dup (‟s‟) 0f6h, 0dfh stack ends
code segment para „code‟ len1 equ $-ary1
sum1 dw ? assume cs:codc,ds:data,ss:stack ary2 db 33h, 44h, 55h, 12h, 78h, h, 0feh, sta proc far 0cdh push ds len2 equ $-ary2 xor ax,ax sum2 dw ? push ax data ends mov ax,data
pushf mov ds,ax
mov ax,len1 mov cx,[bp+6] ; get array lenth push ax mov bx,[bp+4] ; get offset
address lea ax,ary1
push ax xor ax,ax ; sum=0 call sum add1: add al,[bx] mov ax,len2 adc ah,0 push ax inc bx
loop add1 lea ax,ary2
push ax mov [bx],ax call sum popf ret pop cx sta endp pop bx sum proc pop ax push bp pop bp
ret 4 mov bp,sp
push ax sum endp push bx code ends push cx end sta
14.阶乘 问题描述:
确定变量NUMB的阶乘,把结果存入变量FNUMB。变量NUMB的值大于0且小于8。 代码:
data segment call factor num db 3 x1: mov nj,ax nj dw ? pop cx data ends ret stack segment stack „stack‟ sta endp db 200 dup(‟s‟) stack ends factor proc push ax code segment para „code‟ sub ax,1
jne fcon assume cs:code,ds:data,ss:stack
sta proc far pop ax push ds jmp retun
fcon: call factor xor ax,ax
push ax x2: pop cx
mul cl mov ax,data
Retun: ret mov ds,ax
push cx factor endp
code ends mov ah,0
end sta mov a1,num
14.16进制数转换为ASCII码 CHANGE MACRO LOCAL P1
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- vipyiyao.com 版权所有 湘ICP备2023022495号-8
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务