初学汇编- 编程语言,课程设计1

    xiaoxiao2021-03-25  130

     本周开始晚上学习王爽大大的汇编语言,这次真的是一页一页的循序渐进学习的,^^, 昨晚用了三个多小时,把课程设计1重新写了一遍,看到程序运行起来还是很有成就感的,所以来分享一下

    assume cs:code,ds:data,ss:stack data segment db '1975','1976','1977','1978','1979','1980','1981','1982','1983' db '1984','1985','1986','1987','1988','1989','1990','1991','1992' db '1993','1994','1995' dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 dw 11542,14430,15257,17800 data ends stack segment dw 16 dup(0) stack ends temp segment db 16 dup(0) temp ends table segment db 21 dup ('year summ ne ?? ') table ends code segment start: ;**把数据移动到table 段进行整理 mov ax,data mov ds,ax mov ax,stack mov ss,ax mov sp,20h ;es:bp指向table 段。 ;data看做三个数组,首地址分别是0,84,168,元素长度分别是1byte、4byte、2byte ;table 可以看做一个数组,数组中的元素为结构体(21个), ;结构体中有4个元素,每个元素的首地址为0,5,10,13 ;cx 为循环变量21,si 四字节进位,bx,2字节进位 mov ax,table mov es,ax mov bp,0 mov si,0 mov bx,0 mov cx,21 s: mov ax,0[si] mov es:[bp].0,ax mov ax,0[si+2] mov es:[bp].[2],ax mov byte ptr es:[bp].[4],0 mov ax,84[si] mov es:[bp].[5],ax mov dx,84[si+2] mov es:[bp].[7],dx ;dx|ax 被除数 mov di,168[bx] mov es:[bp].[10],di ;di 除数 div di mov es:[bp].[13],ax add si,4 add bx,2 add bp,16 loop s mov ax,temp mov ds,ax mov si,0 ; ds:si 临时字符串区, es:di 源数据区 mov di,0 ;**循环显示每一行数据,每一行数据做四个操作, ;显示年份(字符串),显示收入(双字型),显示人数(字型),显示平均(字型) mov dh,2 mov cx,21 flag: mov dl,20 push cx mov cl,71h push ds push si push es push di pop si pop ds call show_str pop si pop ds push ax push dx mov ax,es:[di][5] mov dx,es:[di][7] call dwtoc pop dx pop ax mov dl,28 call show_str mov ax,es:[di][10] call wtoc mov dl,39 call show_str mov ax,es:[di][13] call wtoc mov dl,48 call show_str add di,16 add dh,1 pop cx loop flag mov ax,4c00h int 21h ;**屏幕显示子程序 ;-功能:在指定位置,以指定颜色,显示以0结尾的字符串 ;参数:dh 行,dl 列 ,cl 颜色, ds:si 指向字符串 show_str: ;压栈 push ax push es push di push si push cx ;操作 mov ax,0B800h mov es,ax mov di,0 mov al,160 mul dh mov di,ax mov al,2 mul dl add di,ax ; es:di定位显存 mov ch,0 mov al,cl show_flag: mov cl,ds:[si] jcxz show_ok mov es:[di],cl mov es:[di+1],al inc si add di,2 jmp show_flag show_ok: ;出栈 pop cx pop si pop di pop es pop ax ;返回 ret ;**支持双字型整数 到 字符串转换子程序 ;功能:讲一个dw 类型数字转换为一个字符串 ;参数: dx|ax 为保存的数字 ;返回值:ds:si执行转换之后的字符串。 dwtoc: ;压栈 push si push cx ;操作 mov cx,0 push cx dwtoc_cal: mov cx,10 call dwdiv add cx,30h push cx mov cx,ax jcxz dwtoc_and jmp dwtoc_cal dwtoc_and: mov cx,dx jcxz dwtoc_comb dwtoc_comb: pop cx mov ds:[si],cl jcxz dwtoc_ok inc si jmp dwtoc_comb dwtoc_ok: ;出栈 pop cx pop si ;返回 ret ;**字形数字转字符串 ;功能:字型数字转换为字符串 ;参数:ax :要转换的数字 ;返回值:ds:si转换后字符串首地址。 wtoc: ;压栈 push si push dx push cx push bx ;操作 mov dx,0 push dx wtoc_cal: mov bx,10 ;div word ptr 000ah div bx add dx,30h push dx mov cx,ax jcxz wtoc_comb mov dx,0 jmp wtoc_cal wtoc_comb: pop cx mov ds:[si],cl jcxz wtoc_ok inc si jmp wtoc_comb wtoc_ok: ;出栈 pop bx pop cx pop dx pop si ;返回 ret ;**双字不溢出除法 ;功能:不会溢出的双字除法 ;参数:dx|ax 被除数, cx 除数 ;返回:dx|ax 商, cx 余数 dwdiv: ;压栈 push bx ;操作 push ax mov ax,dx mov dx,0 div cx mov bx,ax ; 商暂时保存 pop ax div cx mov cx,dx mov dx,bx ;出栈 pop bx ;返回 code ends end start 里面的注释写的比较详细, 其他的就不多说了,

    附个效果图,

    这是目前为止一次写的最长的一个汇编程序了,大概有250行左右,不过即使是再短的程序, 在写代码之前的计算方法设计和存储空间安排都十分重要。

    转载请注明原文地址: https://ju.6miu.com/read-8052.html

    最新回复(0)