1. 程式人生 > >組合語言實驗七

組合語言實驗七

已知 data 段:

assume cs:codesg
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個字串

  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型資料 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型資料 data ends table segment db 21 dup ('year summ ne ??') table ends

程式設計,將 data 段中的資料按如下格式寫入到 table 段中,並計算 21 年中的人均收入(取整),結果也按照下面的格式儲存在 table 段中。

程式碼和分析如下:

# 思考兩個問題: 1. 要處理的資料在什麼地方?(資料來源在 data 段中; 資料目的在 table 段中)   2. 要處理的資料有多長?
# 
# 將 data 段中的資料看作多個數組; table 段中的資料看作一個數組,陣列的每一個元素是一個結構體
# 
# 對 data 段中的資料進行**重排**, 成一個結構體的陣列, 只需迴圈 21 次, 每次完成一個數組結構體元素的賦值
#
# [bx].idata[di] 用來定位 table 段 ; [bp + si] 用來定位 data 段
#
# 1. 初始化操作:
#    
#    1)取得data段和table的段的起始地址,分別用 ds:si 和 es:di 指向
#    
2)初始化cx的值為21,也就是迴圈次數為21 # 3)引入bx,控制si的增量保持為4。原因:僱員和人均收入記錄中的每個資料項長度是2,而其它每個資料項的 # 長度均為4,為了能在一個迴圈中進行操作,必須使得他們的增量保持一致 # 4)入口地址:標號next: # # 2. 迴圈體 # # 1)移動年份資料 # 2)移動總收入資料 # 3)sub si,bx # 4)移動僱員資料 # 5)進行除法操作求出人均收入,並移動人均收入 # # 3. 引數修改 # # 1)si增加4,用si指向每個資料項 # 2)di增加16,用di指向每行 # 3)bx增加2,與sub si,bx配合控制僱員和人均收入兩個資料在data段中的位置 #  # 4. 迴圈控制 # loop next #  # 5. 程式返回 # mov ah,4ch # int 21h assume cs:codesg 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個字串 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型資料 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型資料data ends data ends table segment db 21 dup ('year summ ne ?? ') table ends codesg segment start: mov ax,data mov ds,ax mov ax,table mov es,ax ;將源資料和目的資料的段地址記錄在段暫存器中 sub si,si sub di,di ;分別存放兩個資料段的偏移地址, 初始值是 0 mov cx,21 sub bx,bx ;這裡引入bx是為了很好的控制一次迴圈過後 si 的增量保持在 4 # 下面移動年份資料, 一次迴圈需要移動 4 個位元組 next: mov ax , ds:[si] mov es:di , ax ;先移動頭 2 個位元組 mov ax , ds:[si+2] mov es:[di+2] , ax ;再移動後 2 個位元組 mov byte ptr es:[di+4] , 20h ;向目的地的年份資料後面放一個空格(大小為一個位元組) # 下面移動收入資料, 一次迴圈需要移動 4 個位元組 mov ax , ds:[si+84] mov es:[di+5] , ax ;先移動頭 2 個位元組 mov ax , ds:[si+86] mov es:[di+7] , ax ;再移動後 2 個位元組 mov byte ptr es:[di+9] , 20h ;向目的地的收入資料後面放一個空格(大小為一個位元組) # 下面移動僱員資料, 一次迴圈需要移動 2 個位元組 sub si , bx ;bx 用來補齊 mov ax , ds:[si+168] mov es:[di+10] , ax ;先移動頭 2 個位元組 add si , bx ;還原 si mov byte ptr es:[di+12] , 20h ;向目的地的僱員資料後面放一個空格(大小為一個位元組) # 計算平均收入資料 mov dx , ds:[si+86] ; 移動被除數高 16 bit mov ax , ds:[si+84] ; 移動被除數低 16 bit div word ptr es:[di+10] ; 進行除法操作求出人均收入 mov es:[di+13],ax ; ax預設儲存商, bx預設儲存餘數 mov byte ptr es:[di+15],20h add si , 4 add di , 16 ; si-> 0 4 8 12 add bx , 2 ; 如果不加 2 的話, 會遺漏資料--> ; bx-> 0 2 4 6 8 10 12 loop next ; 3 7 9 13 28 38 130 mov ah , 4ch int 21h codesg ends end start