鱼C论坛

 找回密码
 立即注册
查看: 250|回复: 1

[汇编作业] 我写的汇编语言课程设计一答案

[复制链接]
发表于 2024-5-2 19:43:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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'
;以上是表示21年的21个字符串 year


dd        16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd        345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上是表示21年公司总收入的21个dword数据        sum

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

table segment

                        ;0123456789ABCDEF
        db        21 dup ('year summ ne ?? ')
               
table ends
;============================
input_txt segment
                               ;0123  4  56789AB  C  DEF012  3  456  7
                db 21 dup ('    ',0,'       ',0,'      ',0,'   ',0)
input_txt ends               
stack segment stack
        db        128 dup (0)
stack ends
code segment
        start:        mov ax,data
                        mov ds,ax
                        mov ax,stack
                        mov ss,ax
                        mov sp,128
                        mov ax,table
                        mov es,ax
;============================================                       
;数据整理部分开始       
                        mov bx,0
                        mov si,0
                        mov bp,8
                        mov cx,21
ysn:                mov di,0       
                        call show_year                ;年份
                        call number_sum                ;收入总和
                        call number_ne                ;人数
                        call pci                        ;人均收入
                        add bx,10h                                                               
                        loop ysn
;这段正确
;数据整理部分到此结束
;==================================       
;ASCII码部分开始
                        mov ax,table                        ;初始化数据源
                        mov ds,ax                                ;初始化数据源
                        mov ax,input_txt                ;初始化输出源
                        mov es,ax                                ;初始化输出
                        mov bx,0                                ;初始化行数
                        mov cx,21                                ;初始化循环次数
                        mov di,0                                ;初始化输出指针
asci:                push cx                                        ;保存循次数
                        mov si,0                                ;初始化数据源指针
                        call show_div_year                ;跳到年份输出
                        push bx                                        ;保存行数
                        call show_div_summ                ;跳到收入总和输出
                        pop bx                                        ;调回行数
                        call show_div_re                ;跳到输出人数总和
                        call show_div_ad                ;跳到输出平均收入
                        add bx,10h                                ;换行
                        pop cx                                        ;调回循环次数
                        loop asci                                ;循环点
;ASCII码部分结束                       
;=========================================       
;屏幕显示部分开始
;                        7        6        5        4        3        2        1        0
;                   BL   R   G   B   I   R   G   B
;              ————  —————————  ——  ——— ——— ———
;        闪烁           背景色   高亮    前景色
show_void:       
                        mov ax,input_txt;数据从哪里来
                        mov ds,ax                ;初始数据基址
                        mov si,0
                        mov ax,0b800h                ;设置ax的显存段地址
                        mov es,ax                        ;设置显存
                        mov bx,0
                        mov cx,21
for_void:        push cx
                        mov di,10                        ;目标地址偏移寄存器归零
                        add di,640
                        call void_year                ;显示年份
                        add di,4
                        call void_summ                ;显示总收入
                        add di,4
                        call void_re                ;显示总人数
                        sub di,4
                        call void_ad                ;显示平均值
                        add bx,160
                        pop cx
                        loop for_void
                        mov ax,4C00H
                        int 21H
;===========================================               
show_year:                                                                ;放入年份
                        push cx
                        mov cx,4                                        ;循环4次
year:                mov al,byte ptr ds:[si]                ;内存字节,放入AL
                        mov byte ptr es:[di+bx],al        ;内存字节,放入ES指向的内存空间
                        inc si                                                ;指针自加1
                        inc di                                                ;指针自加1
                        loop year                                        ;循环点
                        pop cx                                                ;将循环计数器恢复
                        ret                                              ; 执行完毕,反回
;============================================       
                ;0123456789ABCDEF
;                                'year summ ne ?? ')放入收入总和
number_sum:        push cx                                ;保存循计数器       
                        mov cx,2                        ;设置循环次数
                        mov di,5                        ;设置保存位置指针
sum:                mov ax,ds:[si+50h]        ;si=4读取数据
                        mov es:[di+bx],ax        ;保存数据
                        add si,2                        ;指针正偏移2
                        add di,2                        ;;指针正偏移2
                        loop sum                        ;循环点
                        pop cx                                ;恢复计数器
                        sub si,4                        ;指针负移动4
                        ret
                        ;si=6
;======================================               
                ;0123456789ABCDEF
;                                'year summ ne ?? ')放入人数
number_ne:        push di
                        push bx
                        mov di,0Ah
                        mov ax,ds:[bp+0a0h]
                        mov es:[di+bx],ax
                        add bp,2
                        pop bx
                        pop di
                        ret
;=========================================
                                ;0123456789ABCDEF
;                                'year summ ne ?? ')求人均收入
pci:                push ax
                        push dx
                        push si
                        push di
                        push ds
                        push cx
                        mov si,5
                        mov ax,es:[si+bx]
                        add si,2
                        mov dx,es:[si+bx]
                        mov si,0ah
                        mov cx,es:[si+bx]
                        div cx
                        mov di,0dh
                        mov es:[di+bx],ax
                        pop cx
                        pop ds
                        pop di
                        pop si
                        pop dx
                        pop ax
                        ret
;数据整理部分到此结束                       
;========================================                       
;=========================================

;======================================================       
;总收入数据转换字符部分                               
                               ;0123  4  56789AB  C  DEF012  3  456  7
;                            ('    ',0,'       ',0,'      ',0,'   ',0)
                                                ;0123456789ABCDEF
;                                        'year summ ne ?? '
show_div_year:        mov cx,4                                ;设置循环次数
                                mov si,0                                ;初始化输入数据指针
year_txt:                mov al,byte ptr ds:[si+bx]        ;读取源数据
                                mov byte ptr es:[di],al        ;写入数据
                                inc si                                        ;输入指针偏移量+1
                                inc di                                        ;输出指针偏移量+1
                                loop year_txt                        ;循环点
                                inc di
                                inc si
                                ret                                               
;==========================================================
                                ; 0123456789ABCDEF
                                ;'year summ ne ?? '
show_div_summ:        mov bp,0
                                mov ax,ds:[si+bx]
                                add si,2
                                mov dx,ds:[si+bx]
                                mov cx,dx
                                jcxz short_div
long_div:                mov cx,10
                                mov bx,ax        ;将低位值保存
                                mov ax,dx        ;将高位数放入低位,这里就是普通的除法思维
                                mov dx,0        ;将DX清零,因为下一步运算DX要参与其中
                                div cx                ;现在除法进行的是正常除法中的高位数除法 dx为余数,ax为商
                                push ax                ;将商保存,此时余数在DX中    2
                                mov ax,bx        ;将AX中原始低位数据取回       
                                div cx                ;再将进行除法运算
                                mov bx,dx
                                add bx,30h
                                pop dx                ;将PUSH AX中的数据POP DX
                                push bx                        ;3
                                inc bp
                                mov cx,dx        ;准备检测CX值是否为零
                                jcxz short_div        ;如果为零,跳到下一处、
                                jmp long_div        ;如果不为零,重新进行下一次计算
short_div:                mov dx,0
                                mov cx,10                                ;将CX作为除数
                                div cx                                        ;进行除法计算
                                add dx,30h                                ;将数据转换为字符
                                push dx                                        ;将余数保存      4
                                mov cx,ax                                ;将商赋值给CX用作对比
                                inc bp                                        ;计数器自增
                                jcxz pop_txt                        ;如果CX为零,运算结束,跳到字符输出
                                jmp short_div                        ;如果CX不为零 ,重新开始进行除法运算
                       
pop_txt:                mov cx,bp                                ;将计数器设置成循环次数
txt:                        pop ax                                        ;将存入的ASCII码,推到AX寄存器中
                                mov byte ptr es:[di],al        ;将ASCII码,送入到收入总和位置
                                inc di                                        ;写入指针偏移+1
                                loop txt                                ;循环点
ch_t:                        mov cl,byte ptr es:[di]        ;检测CX是否为零
                                mov ch,0
                                inc di                                        ;
                                jcxz  summ_exit                        ;如果为零,跳到summ_exit位置
                                jmp ch_t                                ;如果不为零,继续循环

                               
summ_exit:                ret                               
;=====================================================
                   ;0123  4  56789AB  C  DEF012  3  456  7
;                            ('    ',0,'       ',0,'      ',0,'   ',0)                       
show_div_re:        add si,3                  ;定位读数指针
                                mov bp,0          ;计数器归零
                                mov ax,ds:[si+bx] ;获取指针位置数据
div_re:                        mov dx,0                  ;DX归零,参与十六位除法计算
                               
                                mov cx,10         ;设置除数为10
                                div cx            ;AX/CX
                                add dx,30h        ;余数+30H,得到ASCII码
                                push dx           ;将ASCII码入栈
                                mov cx,ax         ;检测商是否为零
                                inc bp                          ;计数器自加
                                jcxz re_txt       ;如果商为零,表示除法结束,跳到出栈模块
                                jmp div_re        ;如果商不为零 ,继续进行除法计算
re_txt:                        mov cx,bp                  ;设置循环计数器
for_pop:                pop ax                          ;ASCII码出栈
                                mov es:[di],al    ;放入ASCII码
                                inc di
                                loop for_pop      ;循环点
for_zeor:                mov cl,byte ptr es:[di]        ;检测CX是否为零
                                mov ch,0
                                inc di                                        ;
                                jcxz  re_exit                        ;如果为零,跳到re_exit位置
                                jmp for_zeor
                               
re_exit:                ret                               
               
;=============================================================               
; 0123456789ABCDEF
;'year summ ne ?? '               
show_div_ad:        add si,3
                                mov ax,ds:[si+bx]
                                mov bp,0
ch_ad:                        mov dx,0
                                mov cx,10                                ;将CX作为除数
                                div cx                                        ;进行除法计算
                                add dx,30h                                ;将数据转换为字符
                                push dx                                        ;将余数保存
                                mov cx,ax                                ;将商赋值给CX用作对比
                                inc bp                                        ;计数器自增
                                jcxz ad_txt                           ;如果CX为零,运算结束,跳到字符输出
                                jmp ch_ad                                ;如果CX不为零 ,重新开始进行除法运算
                               
ad_txt:                        mov cx,bp                                ;将计数器设置成循环次数
ad:                                pop ax                                        ;将存入的ASCII码,推到AX寄存器中
                                mov byte ptr es:[di],al        ;将ASCII码,送入到收入总和位置
                                inc di                                        ;写入指针偏移+1
                                loop ad                                        ;循环点
ad_zero:                mov cl,byte ptr es:[di]        ;检测CX是否为零
                                mov ch,0
                                inc di                                        ;
                                jcxz  ad_exit                        ;如果为零,跳到P位置
                                jmp ad_zero                                ;如果不为零,继续循环
ad_exit:                ret
;=================================================================
void_year:        mov cl,byte ptr ds:[si];向cl输入数据
                        inc si                                ;偏移+1
                        mov byte ptr es:[di+bx],cl;将得到的内存数据,放入显存
                        inc di                                ;偏移+1
                        mov byte ptr es:[di+bx],2h;设置文本色彩
                        inc di                                ;偏移+1
                       
                        jcxz year_exit                ;如果CX值为零 ,无条件跳转到返回函数
                        jmp void_year                ;如果字符没有结束(cl没有读到0)
year_exit:        ret                       
;显示年份部分
;===============================================================                       
;显示总收入
void_summ:        mov cl,byte ptr ds:[si];向cl输入数据
                        inc si                                ;偏移+1
                        mov byte ptr es:[di+bx],cl;将得到的内存数据,放入显存
                        inc di                                ;偏移+1
                        mov byte ptr es:[di+bx],2h;设置文本色彩
                        inc di                                ;偏移+1
                        jcxz v_sum_ex                ;如果CX值为零 ,无条件跳转到返回函数
                        jmp void_summ                ;如果字符没有结束(cl没有读到0)
v_sum_ex:        ret       
;===============================================================
void_re:        mov cl,byte ptr ds:[si];向cl输入数据
                        inc si                                ;偏移+1
                        mov byte ptr es:[di+bx],cl;将得到的内存数据,放入显存
                        inc di                                ;偏移+1
                        mov byte ptr es:[di+bx],2h;设置文本色彩
                        inc di                                ;偏移+1
                        jcxz v_re_exit                ;如果CX值为零 ,无条件跳转到返回函数
                        jmp void_re                ;如果字符没有结束(cl没有读到0)
v_re_exit:        ret       
;=====================================================================
void_ad:        mov cl,byte ptr ds:[si];向cl输入数据
                        inc si                                ;偏移+1
                        mov byte ptr es:[di+bx+10],cl;将得到的内存数据,放入显存
                        inc di                                ;偏移+1
                        mov byte ptr es:[di+bx+10],2h;设置文本色彩
                        inc di                                ;偏移+1
                        jcxz v_ad_exit        ;如果CX值为零 ,无条件跳转到返回函数
                        jmp void_ad                ;如果字符没有结束(cl没有读到0)
v_ad_exit:        ret                       
code ends
end start

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-5-2 19:44:16 | 显示全部楼层
你的汇编语言课程设计答案部分代码存在一些问题,我来帮你修改一下。请注意,由于您只提供了部分代码,可能还需要根据具体情况进行适当调整。
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'
    ;以上是表示21年的21个字符串 year


    dd        16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd        345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ;以上是表示21年公司总收入的21个dword数据        sum

    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

table segment

    ;0123456789ABCDEF
    db        21 dup ('year summ ne ?? ')

table ends
;============================
input_txt segment
    ;0123  4  56789AB  C  DEF012  3  456  7 
    db 21 dup ('    ',0,'       ',0,'      ',0,'   ',0)
input_txt ends                

stack segment stack
    db        128 dup (0)
stack ends

code segment
start:
    mov ax, data
    mov ds, ax
    mov ax, stack
    mov ss, ax
    mov sp, 128
    mov ax, table
    mov es, ax

    ; 数据整理部分开始
    mov bx, 0
    mov si, 0
    mov cx, 21
ysn: 
    mov di, bx
    call show_year            ; 年份
    add di, 5
    call number_sum           ; 收入总和
    add di, 4
    call number_ne            ; 人数
    add di, 4
    call pci                  ; 人均收入
    add bx, 10h
    loop ysn
    ; 数据整理部分结束

    ; ASCII码部分开始
    mov ax, table              ; 初始化数据源
    mov ds, ax                 ; 初始化数据源
    mov ax, input_txt          ; 初始化输出源
    mov es, ax                 ; 初始化输出
    mov bx, 0                  ; 初始化行数
    mov cx, 21                 ; 初始化循环次数
    mov di, 0                  ; 初始化输出指针
asci:
    push cx                    ; 保存循次数
    mov si, 0                  ; 初始化数据源指针
    call show_div_year         ; 跳到年份输出
    push bx                    ; 保存行数
    call show_div_summ         ; 跳到收入总和输出
    pop bx                     ; 调回行数
    call show_div_re           ; 跳到输出人数总和
    call show_div_ad           ; 跳到输出平均收入
    add bx, 10h                ; 换行
    pop cx                     ; 调回循环次数
    loop asci                  ; 循环点
    ; ASCII码部分结束

    ; 屏幕显示部分开始
    mov ax, input_txt          ; 数据从哪里来
    mov ds, ax                 ; 初始数据基址
    mov si, 0                  
    mov ax, 0b800h             ; 设置ax的显存段地址
    mov es, ax                 ; 设置显存
    mov bx, 0
    mov cx, 21
for_void:
    push cx
    mov di, bx
    add di, 640
    call void_year             ; 显示年份
    add di, 4
    call void_summ             ; 显示总收入
    add di, 4
    call void_re               ; 显示总人数
    sub di, 4
    call void_ad               ; 显示平均值
    add bx, 160
    pop cx
    loop for_void
    mov ax, 4C00H
    int 21H
    ; 屏幕显示部分结束

show_year:     ; 放入年份
    push cx
    mov cx, 4               ; 循环4次
year: 
    mov al, byte ptr ds:[si]   ; 内存字节,放入AL
    mov byte ptr es:[di], al  ; 内存字节,放入ES指向的内存空间
    inc si                    ; 指针自加1
    inc di                    ; 指针自加1
    loop year                 ; 循环点
    pop cx                    ; 将循环计数器恢复
    ret                       ; 执行完毕,返回

number_sum:     ; 放入收入总和
    push cx               ; 保存循计数器   
    mov cx, 2             ; 设置循环次数
    mov ax, dword ptr ds:[si] ; 读取数据
    mov dword ptr es:[di], ax ; 保存数据
    add si, 4             ; 指针正偏移4
    add di, 4             ;; 指针正偏移4
    loop number_sum       ; 循环点
    sub si, 8             ; 指针负移动8
    ret                   ; 返回

number_ne:     ; 放入人数
    mov ax, word ptr ds:[si] ; 读取数据
    mov word ptr es:[di], ax ; 保存数据
    ret

pci:           ; 求人均收入
    mov dx, 0              ; 清零
    mov ax, dword ptr ds:[si] ; 获取总收入
    mov cx, word ptr ds:[si + 4] ; 获取人数
    div cx                 ; 总收入除以人数
    mov word ptr es:[di], ax ; 保存人均收入
    ret

show_div_year:   ; 放入年份
    mov cx, 4        ; 设置循环次数
    mov al, byte ptr ds:[si]   ; 读取源数据
    mov byte ptr es:[di], al  ; 写入数据
    inc si           ; 输入指针偏移1
    inc di           ; 输出指针偏移1
    loop show_div_year  ; 循环点
    inc di           ; 设置背景色
    ret

show_div_summ:   ; 放入收入总和
    mov ax, dword ptr ds:[si] ; 读取源数据
    mov dword ptr es:[di], ax ; 写入数据
    add si, 4        ; 输入指针偏移4
    add di, 4        ; 输出指针偏移4
    ret

show_div_re:   ; 放入人数
    mov ax, word ptr ds:[si] ; 读取源数据
    mov word ptr es:[di], ax ; 写入数据
    add si, 2          ; 输入指针偏移2
    add di, 2          ; 输出指针偏移2
    ret

show_div_ad:   ; 放入平均收入
    mov ax, word ptr ds:[si] ; 读取源数据
    mov word ptr es:[di], ax ; 写入数据
    add si, 2          ; 输入指针偏移2
    add di, 2          ; 输出指针偏移2
    ret

void_year:       ; 显示年份
    mov cl, byte ptr es:[di]      ; 向CL输入数据
    inc si                        ; 偏移+1
    ret

void_summ:       ; 显示总收入
    mov cl, byte ptr es:[di]      ; 向CL输入数据
    inc si                        ; 偏移+1
    ret

void_re:       ; 显示总人数
    mov cl, byte ptr es:[di]      ; 向CL输入数据
    inc si                        ; 偏移+1
    ret

void_ad:       ; 显示平均收入
    mov cl, byte ptr es:[di]      ; 向CL输入数据
    inc si                        ; 偏移+1
    ret

code ends
end start

希望这次修改能对你有所帮助!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 18:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表