1 assume cs:code, ds:data, es:table, ss:stacks 2 3 data segment 4 ;年份 5 db '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982', '1983' 6 db '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992' 7 db '1993', '1994', '1995' 8 ;收入 9 dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514 10 dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000 11 ;员工 12 dw 3, 7, 9, 13, 28, 38, 130, 220, 476, 778, 1001, 1442, 2258, 2793, 4037, 5635, 8226 13 dw 11542, 14430, 15257, 17800 14 data ends 15 16 table segment 17 db 21 dup ('year sumn ne ?? ') 18 table ends 19 20 stacks segment 21 dw 0, 0, 0, 0 22 stacks ends 23 24 code segment 25 start: 26 mov ax, data 27 mov ds, ax ;设置DS的段地址 28 mov ax, table 29 mov es, ax ;设置ES的段地址指向table 30 mov ax, stacks 31 mov ss, ax ;设置SS的段地址 32 mov sp, 8 ;设置SP的栈顶指针 33 mov si, 0 34 mov di, 0 35 mov cx, 21 ;设置最外层的循环次数为21次 36 s: 37 push cx ;利用栈来保护最外层的循环 38 mov cx, 2 ;设置年份和收入的循环次数为2次,因为数据结构逻辑上一样,所以可以在一次循环中同时处理 39 mov bx, 0 40 s1: 41 mov ax, ds:[0+si+bx] ;0看作是数据段中年份的起始地址 42 mov es:[0+di+bx], ax ;0看作是table段中年份的起始地址 43 mov ax, ds:[84+si+bx] ;84看作是数据段中收入的起始地址 44 mov es:[5+di+bx], ax ;5看作是table段中收入的起始地址 45 add bx, 2 46 loop s1 47 add si, bx ;让si来记录走过的字节数,保证在修改table段中的下一行时数据是正确的 48 push si ;想让si同时也处理员工的数据 49 50 mov ax, si ;处理员工的数据 51 mov dl, 2 52 div dl ;因为年份和收入处理时字节长度相同,而员工是它们的一半,所以让si/2后再减2 53 mov si, ax 54 sub si, 2 ;减2就可以对应到数据段员工的数据 55 mov ax, ds:[168+si] ;168看作是数据段中员工的起始地址 56 mov es:[10+di], ax ;10看作是table段中员工的起始地址 57 pop si ;把si真正的值还原回去,保证下次年份和收入能正常处理 58 59 ;处理人均收入的数据 60 mov dx, es:[7+di];被除数的高位 61 mov ax, es:[5+di] ;被除数的低位 62 div word ptr es:[10+di] ;平均收入 63 mov es:[13+di], ax 64 65 add di, 16 66 pop cx 67 loop s 68 69 mov ax, 4C00H 70 int 21H 71 code ends 72 73 end start
本人最近刚开始学汇编语言,以上代码是按照我自己的理解写的,可能不够优化,若有疑问请评论指正,谢谢!
2019-11-01 22:06:09