效果如图:
assume cs:code parameters_stack segment ;程序断点参数传递 db 48 dup(0) parameters_stack ends raw_stack segment ;程序断点保存 db 48 dup(0) raw_stack ends alpha segment db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;0~25 db 'abcdefghijklmnopqrstuvwxyz' ;26~51 db 'HI, WELCOME TO MASM! ' ;52~77 db 'I AM Cncdre FROM CHINA. ' ;78~103 db 'HOW ARE YOU? ' ;104~129 alpha ends code segment Main: ;参数传递 mov ax,parameters_stack mov ss,ax mov sp,32 mov ax,26 push ax ;字符串长度 mov ax,200h push ax ;高地址为字符属性,低地址为0 mov ax,52 push ax ;待显示字符所在偏移地址 mov ax,alpha push ax ;待显示字符所在段 mov ax,2000 push ax ;显存偏移地址 mov ax,0b800h push ax ;显存起始段地址 mov ss:[1],sp ;parameters_stack最高地址存储此时栈顶位置 ;断点保存 mov ax,raw_stack ;call指令会自动压入程序断点地址(ip,短转移) mov ss,ax mov sp,32 call Sub0 mov ax,4c00h int 21h Sub0:;小程序0_字符打印 ;参数压栈顺序: ;字符串长度->高地址为字符属性,低地址为0->待显示字符所在偏移地址 ;->待显示字符所在段->显存偏移地址->显存起始段地址 ;最后在ss:[1]存入sp push ax push es push di push ds push si push cx mov ss:[1],sp ;raw_stack最高地址存储此时栈顶位置 mov ax,parameters_stack mov ss,ax mov sp,ss:[1] ;parameters_stack最高地址读取栈顶位置 pop ax mov es,ax ;显存起始段地址 pop di ;显存偏移地址 pop ds ;待显示字符所在段 pop si ;待显示字符所在偏移地址 pop ax ;低地址为0,高地址为字符属性 pop cx ;字符串长度 s: mov al,ds:[bx+si] mov es:[di],al mov es:[di+1],ah inc si inc di inc di loop s mov ax,raw_stack mov ss,ax mov sp,ss:[1] ;raw_stack最高地址读取栈顶位置 pop cx pop si pop ds pop di pop es pop ax ret ;ret指令会自动弹出程序断点地址赋给ip(短转移) code ends end Main