唯见草木 发表于 2022-4-24 20:29:38

【汇编语言】第八章实验七答案

assume cs:codesg,ss:stacksg
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个字符串,(数组)(0-53h)

    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个数据(54h-0A7h)

    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800
    ;以上是表示21年公司雇员人数的21个word型数据(0A8h-0D1h)
data ends

table segment
    db 21 dup ('year summ ne ?? ')
table ends

stacksg segment
    dw 16 dup(0)
stacksg ends

codesg segment
start:
      mov ax,data
      mov ds,ax ;将data数据的段地址给段寄存器ds

      mov ax,table
      mov es,ax ;将table段的短地址给es,ds已经被data段占用

      mov ax,stacksg
      mov ss,ax
      mov sp,16

      mov bx,0
      mov si,0
      mov di,0
      mov bp,0
      mov cx,21 ;初始化各寄存器的值
;========================================
            s1:   
                  push cx ;让cx入栈,地址ss:000eh
                  mov cx,2    ;这里循环连词是为了将年份和收入分两次读取并写进table,因为每年收入和年份都是四个字节,寄存器一次只能读取两个字节
                        s2:   
                              mov ax,      ;将年份读取到ax,先读取两个字节,例如1975年,第一次读取‘19’,下一次读取‘75’
                              mov es:,ax;将年份写进table,分两次写入
                              mov ax,    ;因为用‘dd’定义,即每年收入占四个字节,和年份一样,用idata定位,与年份一起读取写入
                              mov es:,ax   ;将年份写入table,分两次
                              add si,2         ;累加两位,读取下一个年分,例如1975在内存中为31,39,37,35;第一次是ds:,读取两个字节31,39;下次要读ds:,即37,35
                              add di,2         ;和上面同理
                        loop s2
                  mov di,0    ;di这里要初始化为0,因为是用来定位table里面的写入位置,不像si是定位data里面数据的读取位置,不能一直累加
                  add bx,16   ;跳到table的下一行,开始写新的一行
                  pop cx
            loop s1   ;s1循环的作用是将年份和收入写进table,而员工人数和人均工资不在这面

      mov bx,0
      mov si,0
      mov di,0
      mov bp,0
      mov cx,21   ;初始化各寄存器的值,开始把员工人数写进table
            s3:   
                  mov ax,    ;这里不用再分两次读取,因为就两个字节,寄存器一次就可以搞定
                  mov es:,ax;写入table
                  add si,2            ;累进
                  add bx,16         ;下一行
            loop s3
      mov bx,0
      mov si,0
      mov di,0
      mov bp,0
      mov cx,21   ;初始化各寄存器的值,开始写入工资
            s4:
                  mov ax,   ;低16位写入ax
                  mov dx,   ;高16位写入dx
                  div word ptr ds:   ;word ptr 是为了让电脑知道我们要进行被除数是32位的触发,((dx)*10000h+(ax))/(ds:)
                  mov es:,ax          ; 被除数位32位,求得的商储存在ax中,写入table
                  add si,4            ;加4是因为下一年收入的低十六位与今年收入的低十六位相距4个字节单元
                  add di,2            ;di加2是因为人工数是用dw定义的,即每一年的员工数站两个字节单元
                  add bx,16         ;写下一行
            loop s4
;========================================
      mov ax,4c00h
      int 21h         ;返回函数
codesg ends
end start




如果有错误的地方请纠正,应为还有很多优化的地方,后面会再发一个优化的出来,这个总觉得有点繁琐
不会是前面的所学的基本都要用到,太难了,花了好几个小时

唯见草木 发表于 2022-4-24 20:30:53

写python缩进写习惯了,不对齐不舒服{:5_92:}
页: [1]
查看完整版本: 【汇编语言】第八章实验七答案