在学习了call和ret指令后,我们就可以开始对汇编语言编程进行模块化设计,把现实的问题进行模块化,把它转化成相互联系、不同层次的子问题。

首先我们拿书上的示例程序开刀:

设计一个子程序,可以根据提供的N,来计算N的三次方
assume cs:code
data segment
        dw 1,2,3,4,5,6,7,8
        dd 0,0,0,0,0,0,0,0
data ends
code segment
        start:
                mov ax, data
                mov ds, ax
                mov si, 0
                mov di, 16

                mov cx, 8

        s:      mov bx, [si]
                call cube
                mov [di], ax
                mov [di].2, dx
                add si, 2
                add di, 4
                loop s
        
                mov ax, 4c00h
                int 21h

        cube:   mov ax, bx
                mul bx
                mul bx
                ret
code ends
end start

细细品这段代码:

mov bx, [si]
call cube
mov [di], ax
mov [di].2, dx

我们可以把它拆分成三个步骤:

  1. 获得参数
  2. 对参数进行处理
  3. 返回参数

    和C语言函数相类似

根据这个思想我能不能够,再次设计一个计算累加的程序呢?下面来实战操作下:

根据传入数值,计算前n项和
assume cs:code
data segment
        dw 2,2,3,4,5,6,7,8
        dw 0,0,0,0,0,0,0,0
data ends
stack segment
        dw 128 dup(0)
stack ends
code segment
        start:
                mov ax, data
                mov ds, ax
                mov si, 0
                mov di, 16

                mov cx, 8

        s:      mov bx, [si]
                mov ax, 0
                call cube
                mov [di], ax
                add si, 2
                add di, 2
                loop s

                mov ax, 4c00h
                int 21h

        cube:   push cx
                mov cx, bx
                dec cx
                mov ax, bx
        sum:    
                add ax, cx
                loop sum
                pop cx
                ret
code ends
end start
对上面程序改进了一下,实现求前n项和

屏幕截图 2023-03-21 212541.png

后续附:
可以看到我写的数据段那里,没有从1开始,结合之前文章的分析,看看设置为1的情况是如何?
屏幕截图 2023-03-21 214023.png

低地址变回了1,然而高地址却保留在了80H