1、课程设计,整体思路是通过子程序调用来实现完成整个设计过程用 SI 来寻址数据段,DI 来寻址屏幕显示的内存空间。要 hold 住,不怕麻烦,才可以如有疑惑,欢迎交流 zych_assume cs:codedata segmentdb 1975,1976,1977,1978,1979,1980,1981,1982,1983db 1984,1985,1986,1987,1988,1989,1990,1991,1992db 1993,1994,1995dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514dd 345980,
2、590827,803530,1183000,1843000,2759000,3753000,4649000,5937000dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226dw 11542,14430,15257,17800data endstable segmentdb 21 dup (year summ ne ? )table endscode segmentbegin: mov ax,datamov ds,axmov bx,0mov si,0mov di,0mov ax,tablemov es,axmo
3、v ax,0mov cx,21s: push cxpush dimov cx,4 s1: mov al,dimov es:bx+si,alinc siinc diloop s1pop dipush diinc simov cx,4 s2: mov al,ds:di+84mov es:bx+si,alinc siinc diloop s2pop dipush dimov ax,dimov dl,2div dlmov ah,0mov di,axinc simov al,ds:di+168mov es:bx+si,alinc siinc dimov al,ds:di+168mov es:bx+si,
4、alinc siinc diinc sipop dipush dimov dx,di+86mov ax,di+84shr di,1mov cx,di+168div cxmov es:bx+si,axpop diadd di,4push diadd bx,10hmov si,0pop dipop cxloop scall g1mov ax,table mov ds,axmov si,0mov ax,0b800hmov es,axmov di,280hmov bp,0mov bx,0;_显示年份的call showallmov si,5mov cx,21mov dh,4mov dl,7;118 行
5、,_显示收入的s3: push cxpush axpush dxmov ax,si ;字节地位;120mov dx,si+2;字节高位call dtoc;余数处理后放到 DATA 数据段pop dxmov cl,2pop axcall show_str;显示出来,参数是 dh,dl,cl,其中 dl,dl 不变,ah 加一add dh,1;行加一行;列不变add si,16pop cxloop s3;_以下显示人口数量的mov si,10mov cx,21mov dh,4mov dl,16s4: push cx;二个字节处理push axpush dxmov ax,si ;字节地位call d
6、toc2;余数处理后放到 DATA 数据段pop dxmov cl,2pop axcall show_str;显示出来,参数是 dh,dl,cl,其中 dl,dl 不变,ah 加一add dh,1;行加一行;列不变add si,16pop cxloop s4;_有了以上 2 个处理的基础,这个处理就相对简单了很多了mov si,13mov cx,21mov dh,4mov dl,24s55: push cx;二个字节处理push axpush dxmov ax,si ;字节地位call dtoc2;余数处理后放到 DATA 数据段pop dxmov cl,2pop axcall show_st
7、r;显示出来,参数是 dh,dl,cl,其中 dl,dl 不变,ah 加一add dh,1;行加一行;列不变add si,16pop cxloop s55mov ax,4c00hint 21h;以下是子程序;_清屏g1: mov ax,0B800Hmov es,axmov si,0mov cx,8000s5: mov word ptr es:si,0add si,2loop s5ret;_不会溢出的除法运算divdww: push bxpush axmov ax,dxmov dx,0div cx pop bx push ax mov ax,bx ;高位及时上次运算的余数,已经在 DX 中了di
8、v cx mov cx,dx;余数给 CXpop dx pop bxret;_显示showall: mov cx,21all: push cxmov cx,4row: mov al,ds:bp+simov ah,02hmov es:bx+di,axinc siadd di,2loop rowpop cxmov si,0mov di,280hadd bp,16add bx,0a0hloop allret;_第几行,第几列的显示子程序show_str:push bxpush dxpush sipush cxmov al,0a0hmul dhmov bx,axmov al,2mul dladd bx
9、,axmov si,0mov ax,0b800hmov es,axshow: mov ch,0mov cl,si jcxz ot;数据段中将要显示的除了最后一个,其他都已经加了 30H,不可能为 0 的mov ax,cxpop cxpush cxmov ah,clmov es:bx,axinc siadd bx,2jmp showot: pop cx pop sipop dxpop bxret;_将十进制数字转换为字符串dtoc:push cx ;保护 CX 寄存器push si;保护 simov cx,10mov si,0push si;提前压入一个 0,用作判断使用din: call di
10、vdww;调用不溢出子程序,dx 为商高 16 位,ax 为商低 16 位,cx 为余数push cx;压入余数mov cx,dx;高位商移位到 cxjcxz dout2;高位商为 0 则跳到 dout2 判断低位是否为 0jmp doit;否则跳到 doit 直接进行,压栈运算dout2: mov cx,axjcxz dout1;低位商是否为 0,为 0 去判断余数是否为 0jmp doit;余数部位零就去 doitdout1: pop cxjcxz dout;余数为 0 则跳转到 doutpush cx;如果余数为 0 则还需压入 cx 共下面弹出使用doit: pop cx;弹出余数ad
11、d cx,30hmov ch,1;用来标记压入了 1 个数字了,区别与余数 0000push cx;将余数压入到堆栈中mov cx,10jmp dindout: pop ax ;放到数据口上mov cx,ax;mov ds:si,al;最后一个 0 也写到 DATA 数据段上,用其来判断字符串的结束jcxz ou;正常的数字的高 8 位都是 1inc sijmp doutou: pop sipop cxret ;以下子程序处理 2 个字节的十进制转为字符串dtoc2: push cx ;保护 CX 寄存器push si;保护 simov cx,10mov si,0push si;提前压入一个
12、0,用作判断使用din2: mov dx,0div cx mov cx,ax;商给 CXjcxz dout12;商为 0 则跳到 dout1 判断低位是否为 0push dx;压入余数jmp doit22;否则跳到 doit 直接进行,压栈运算dout12: mov cx,dx;判断余数是否为 0jcxz dout22;余数为 0 则跳转到 doutpush dx;如果余数不为 0 则还需压入余数共下面弹出使用jmp doit22doit22: pop cx;弹出余数add cx,30hmov ch,1;用来标记压入了 1 个数字了,区别与余数 0000,貌似可以不用因为已经加了30Hpush cx;将余数压入到堆栈中mov cx,10jmp din2 ;继续处理其他位dout22: pop ax ;放到数据口上mov cx,ax;mov ds:si,al;最后一个 0 也写到 DATA 数据段上,用其来判断字符串的结束jcxz ou22;正常的数字的高 8 位都是 1inc sijmp dout22ou22: pop sipop cxret code endsend begin