《汇编语言》第三版课程设计1代码实现

果然是绝知此事要躬行。

效果:

代码实现:

两个小小的说明:

  • 所有用到的小程序都是实验10里面的,稍微有点超前的指令是cmp 和 jna 类条件跳转,但是刷了chapter11后,就很容易懂了,另外整个屏幕一行160个字节,正好4列数据,所以每列我配了40个字节,显示出来正好占满整个屏幕。

  • 程序是从第1行而不是第0行开始显示数据的,因为执行EXE文件后,屏幕会自动下移一行,光标闪烁等待用户输入,如果从第0行开始显示,1975 那一年的数据就无法看到了。

以下为具体实现:

assume cs:codesg, ds:data, ss:stacksg

; 所要显示的原始数据

data segment
db '1975','1976','1977','1978','1979','1980','1981','1982' 
db '1983','1984','1985','1986','1987','1988','1989','1990'
db '1991','1992','1993','1994','1995'
;stands for years from 1975 to 1995

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;stands for yearly revenue from 1975 to 1995

dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;stands for number of employees from 1975 to 1995

db 10 dup(0)
; 用于暂存十进制数值
data ends

stacksg segment
  dw 16 dup (0)
stacksg ends

codesg segment
  start: mov ax, data
         mov ds, ax

           mov ax, stacksg
           mov ss, ax
           mov sp, 20h

         mov ax, 0b800h
         mov es, ax

          ; 初始化用于定位的寄存器, bp 为160,从第一行开始
           mov bx, 0
           mov bp, 160
           mov si, 0

         ; 默认在屏幕的1行0列开始显示,cx用于循环,故改用dl保存色值,颜色为绿色
           mov dh, 0
           mov dl, 2

           ; 按行显示,循环21次, cx = 21 
           mov cx, 21
      s: push cx 
           mov di, 0
           call display_years
           call display_revenue
           call display_employees
           call display_per_income
           add bp, 160
           add si, 4 
           add bx, 2
           pop cx
           loop s

           mov ax, 4c00h
           int 21h

; 显示年份
display_years: push dx
               push si
               mov cx, 4
    show_year: mov dh, ds:[si]
                 mov es:[bp + di], dh
                 mov es:[bp + di + 1], dl
                 add di, 2
                 inc si
                 loop show_year

           ; 在年份后的空白处显示空字符
  show_empty0: mov byte ptr es:[bp+di], ' '
                 mov es:[bp + di + 1], dl
                 add di, 2
                   cmp di, 40
                   jna show_empty0

                 pop si
                 pop dx
    end_years: ret

; 显示年收入
display_revenue: push ax
                 push dx
                     push cx
                     mov ax, ds:[21*4+si] ; 年收入是两个字,高位存在dx中,低位存在ax
                     mov dx, ds:[21*4+si+2]
                     mov cx, 10
                     call dtoc  ; 使用实验10的小程序3显示十进制的字符串
                     pop cx
                     pop dx
                     pop ax

                     call show_str ; 使用实验10的小程序1显示十进制的字符串

            ; 在年收入后的空白处显示空字符
   show_empty1: mov byte ptr es:[bp+di], ' '
                  mov es:[bp + di + 1], dl
                  add di, 2
                    cmp di, 80
                    jna show_empty1
   end_revenue: ret


; 显示员工数量
display_employees: push ax
                   push dx
                       push cx
                       mov ax, ds:[21*8+bx]
                       mov dx, 0 
                       mov cx, 10
                       call dtoc  ; 使用实验10的小程序3显示十进制的字符串
                       pop cx
                       pop dx
                       pop ax

                       call show_str ; 使用实验10的小程序1显示十进制的字符串

            ; 在员工数量后的空白处显示空字符
    show_empty2: mov byte ptr es:[bp+di], ' '
                  mov es:[bp + di + 1], dl
                  add di, 2
                    cmp di, 120 
                    jna show_empty2
  end_employees: ret

; 显示年均人收入
display_per_income: push ax
                    push dx
                        push cx
                        mov ax, ds:[21*4+si]
                        mov dx, ds:[21*4+si + 2]
                        mov cx, ds:[21*8+bx]
                        call divdw ; 使用实验10的小程序2先得出人均年收入,高位存放在dx, 低位存放在ax
                        mov cx, 10
                        call dtoc  ; 使用实验10的小程序3显示十进制的字符串
                        pop cx
                        pop dx
                        pop ax

                        call show_str ; 使用实验10的小程序1显示十进制的字符串

            ; 在年均人收入后的空白处显示空字符
    show_empty3: mov byte ptr es:[bp+di], ' '
                   mov es:[bp + di + 1], dl
                   add di, 2
                     cmp di, 160 
                     jna show_empty3
end_per_income: ret

   dtoc: push si
           push di
           push bp 

           mov si, 0
           mov di, 0
           mov bp, cx

     s0: mov cx, bp 
         call divdw

           add cx, 30h
           push cx
           inc si ; si 用来记录总的十进制数的字符串个数, 出栈时用到
           mov cx, ax
           jcxz s1
           jmp short s0

     s1: pop ax
         mov ds:[21*10 + di], al
           dec si
           mov cx, si
           jcxz ok
           inc di
           jmp short s1

     ok: pop bp
         pop di
         pop si
         ret 

   divdw: push bx
          push ax
          mov ax, dx
            mov dx, 0
            div cx
            mov bx, ax

            pop ax
            div cx

            mov cx, dx
            mov dx, bx
            pop bx
          ret

 show_str: push cx
           push si
             mov si, 0
           mov ch, 0
 display: mov cl, ds:[21*10 + si]
            jcxz finish
            mov es:[bp + di], cl
            mov es:[bp + di + 1], dl
             mov ds:[21*10+si], ch
            inc si
            add di, 2
            jmp short display
  finish: pop si 
          pop cx
          ret

codesg ends
end start