首页
社区
课程
招聘
[分享]零基础16位汇编学习之主程序与子程序间的几种参数传递方法
发表于: 2022-2-10 12:51 4858

[分享]零基础16位汇编学习之主程序与子程序间的几种参数传递方法

2022-2-10 12:51
4858

主程序在调用子程序时,一般要向子程序传递一些参数,然后,子程序运行后也要把结果参数传回给主程序,所以一般子程序需要入口参数和出口参数,这里学习三种参数传递方法。
一、寄存器传递参数
在需要调用子程序的时候利用寄存器存放参数作为入口和出口参数,这种方法简单方便,缺点是只能用于参数较少的时候。
例:把一个大写字母转为小写字母的子程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;子程序名:pata
;功能:把大写字母转换为小写字母
;入口参数:al = 字符ascll码
;出口参数:al = 字符ascll码
;说明:如果字符是大写字母,则转换为小写字母,其他字符不变
pata proc
    pushf         ;保护寄存器里面的数据
    cmp al,'A'    ;字符串与大写A做比较
    jb stp        ;小于大写A则跳转
    cmp al,'Z'    ;字符串与大写Z作比较
    ja stp        ;大于大写Z则跳转
    add al,20h    ;是大写字母加20h就是ascll码串的小写字母
stp:popf
    ret           ;返回
pata endp

二、利用约定存储单元传递参数
第二种方法是利用约定的内存单元里的数据来传递参数,这种方法的优点是子程序要处理的数据和结果都有单独的内存单元,写程序不容易出错
例:实现32位数相加的子程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
;子程序名:pata1
;功能:32位数相加
;入口参数:date1和date2分别存放相加的32位数
;出口参数:date3缓冲区存放
;说明:132位数据存放依次为’高高低低‘的原则
       2、可能产生的进位存放在date3开始的第5字节中
pata1 proc
    pshu ax       
    pshu cx
    pshu si            ;保护寄存器里面的数据
    mov cx,2           ;因为用16位寄存器计算所以循环加两次
    xor si,si          ;si寄存器置0
pa1:
    mov ax,word ptr date1[si]    ;提取date1段里面的16位数据到ax
    adc ax,word prr date2[si]    ;ax和date2段里面的16数据进位相加
    mov word ptr date3[si],ax    ;把结果存入date3单元缓冲区
    inc si                      
    inc si                        ;si指向另外16位数据
    loop pa1                       ;再循环相加一次
    mov al,0                       ;al置0,用于判断是否有进位
    adc al,0                       ;如果相加的数据有进位
    mov byte ptr data3+4,al        ;把进位数传递到date3的第5字节中
    pop si                        
    pop cx
    pop ax                         ;寄存器恢复
    ret                            ;返回
pata1 endp

例2:把ascll码表示的十进制数字转换为二进制数的子程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
;子程序名:pata2
;功能:把ascll码表示的十进制数字转换为二进制数
;入口函数:ds:bx缓冲区里面的数据
;出口函数:ax,得到的二进制数存到ax寄存器里
;说明:设表示的二进制数不大于65535
 
pata2 proc
    push bx
    push cx
    push dx          ;保护寄存器
    xor ax,ax        ;ax置0
    mov cl,[bx]      ;把ds:[bx]处的置赋予cl
    inc bx           ;bx指向下一位数据
    xor ch,ch        ;ch清0
    jcxz pta2        ;如果cx是0则跳转
pta1:
    mov dx,10        ;dx = 10
    mul dx           ;dx×10 二进制表示1010
    mov dl,[bx]      ;取下一个数字符到10后面
    inc bx           ;bx指向下一位
    and dl,0fh       ;把dl转成bcd码
    xor dh,dh        ;dh(10)清0
    add ax,dx        ;把值和ax相加存到ax寄存器
    loop pta1       
pta2:
    pop dx
    pop cx
    pop bx            ;恢复寄存器
    ret
pata2 endp

三、利用堆栈传递参数
如果使用堆栈传递入口参数,把需要传递的参数依次压入堆栈,子程序从堆栈中取入口参数,如果使用堆栈传递出口参数,把需要传递的参数依次压入堆栈,子程序从堆栈中取出口参数。
例1:写一个测量字符串长度的子程序,设字符串为0结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
;子程序名:pata3
;功能:测量字符串长度
;入口参数:字符串起始地址段值和偏移在堆栈中
;出口参数:ax= 字符串长度
pata3 proc
    push bp       
    mov bp,sp    ;把堆栈sp赋值给bp,为取参数做准备
    push ds        ;保护段寄存器
    push si        ;保护偏移地址
    mov ds,[bp+6]    ;取入口参数
    mov si,[bp+4]   
    mov al,0        ;al置0
pat3:   
    cmp al,[si]     ;判断是不是结尾0
    jz pat4          ;如果是0则跳转pat4
    inc si            ;不是0则si加1
    jmp pat3         ;跳转到pat3继续计算
pat4:
    mov ax,si        ;si的值就是字符串的长度
    sub ax,[bp+4]    ;ax减去段寄存器地址的多余长度得到具体长度
    pop si
    pop ds
    pop bp            ;恢复寄存器数据
    ret
pata3 endp

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//