assume cs:code,ds:data,es:table
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'
;db 字节型数据,这里'1975'不是我们所理解的十进制1975而是字符串
;所以每个年份占4个字节,总共占了21*4=84个字节
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;db(dword)占4字节,所以收入占了21*4=84字节
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;dw 每个数据占2个字节,共占21*2=42字节
data ends
table segment
db 21 dup ('year summ ne ?? ') ;引号里的字母无所谓后面会被覆盖这里只是提示录入的是什么信息
table ends
code segment
start: mov ax,data
mov ds,ax ; ds:0指向data中的第一个数据
mov ax,table
mov es,ax
mov bx,0
mov si,0
mov di,0 ;原来我也想过用栈,但是入栈是反向存入数据,不对,我也不知道用几个寄存器
;先定义这么多,多退少补
mov cx,21 ;因为有21行table,其实这一道题也就是凑每一行的内容,然后其他行都是循环得到
s: mov ax,[bx]
mov es:[si],ax ;将ds:[bx]的数据放入es:[si]中
mov ax,[bx+2]
mov es:[si+2],ax ;到这里'1975'放入table第一行它的位置,下面是放空格
mov byte ptr [si+4],20h ;看书上表格可以知道这是第5个位置所以是si+4,ASCII码空格是20h
mov ax,[bx+84] ;因为收入的数据放在ds:84
mov es:[si+5],ax
mov ax,[bx+86]
mov es:[si+7],ax ;年收入的数据录入了,下面是空格
mov byte ptr [si+9],20h ;因为ax占两个字节所以是si+9
mov ax,[di+168] ;原本这里我写的是[bx+168],但是循环到下一行你会发现年份和收入和下一个数据的间隔是4个字节
mov es:[si+10],ax ;但是雇员数间隔是dw型数据,只有两个字节,所以不能用bx表示了
mov byte ptr [si+12],20h
mov ax,[bx+84]
mov dx,[bx+86] ;因为收入是db数据,所以用ax存放低位,dx存放高位数据
div word ptr es:[si+10] ;用dx:ax中的数据除以ds:[di+168]中的数据
mov es:[si+13],ax ;因为商存在ax中,所以把ax中的数据转到es:[si+13]中
;第一行数据录入完了,开始下一行,然后看还有哪些数据是需要改动的,哪些是固定不变的
add bx,4 ;bx表示下一个db类型的数据,所以加4
add di,2 ;di表示dw型数据
add si,10h ;表示将es指向下一行数据首地址
loop s
mov ax,4c00h
int 21h
code ends
end start