开始看解答上面的代码一大篇,大惊,再一细看,觉得代码不是很好。王爽把参数的栈传递放置于附录中讲解,也是寥寥数笔尔,看了还觉不是甚爽。回头到王爽fans站里找了个博客,整个博客仅一图片,不过高手就是不同,一切尽在不言中,看罢图片( 函数参数栈传递),大有裨益,回头写下这题代码。hoho~~
;
----------------------------------------------------------------------
; Program :将datasg中的字符串输入到屏幕指定位置 ,并要求设置字符串格式
; Created by :刺猬
; ----------------------------------------------------------------------
assume cs :codesg , ds :datasg , ss :stacksg
datasg segment
db 'welcome to masm!' , 0
datasg ends
stacksg segment
db 16 dup ( 0 )
stacksg ends
codesg segment
main: mov ax , datasg
mov ds , ax
mov ax , stacksg
mov ss , ax
mov sp , 16
mov bp , sp
sub sp , 6 ; 以下三个是局部变量,用堆栈保存 翻译成C语言
mov word ptr [bp- 6 ] , 2h ; int cl = 02h
mov word ptr [bp- 4 ] , 3 ; int dl = 3
mov word ptr [bp- 2 ] , 8 ; int dh = 8
push [bp- 2 ] ; 这里用栈传递三个参数 show_str ( cl , dl , dh )
push [bp- 4 ]
push [bp- 6 ]
call show_str
add sp , 12
mov ax , 4c00h
int 21h
show_str: push bp
mov bp , sp
dec word ptr [bp + 8 ] ;( dh- 1 ) * 160 这里是计算行数
mov ax , 160
mul word ptr [bp + 8 ]
mov [bp + 8 ] , ax
dec word ptr [bp + 6 ] ;( dl- 1 ) * 2 这里是计算列数
mov ax , 2
mul word ptr [bp + 6 ]
mov [bp + 6 ] , ax
mov ax , 0b800H ; 设置es :b800H
mov es , ax
mov bx , [bp + 8 ] ; 设置bx,即是偏移地址
add bx , [bp + 6 ]
mov si , 0 ; si记录ds中的偏移
mov di , 0 ; 自然 di是记录es中的偏移了
s: mov cl , ds:[si]
mov ch , 0
jcxz ok ; 发现是0,即到了字符串结尾了
mov es:[bx + di] , cx ; 如果不是结尾那么就拷贝
mov ax , [bp + 4 ]
mov es:[bx + di + 1 ] , ax
add di , 2
inc si
jmp s ; 循环
ok: pop bp
ret
codesg ends
end main
; Program :将datasg中的字符串输入到屏幕指定位置 ,并要求设置字符串格式
; Created by :刺猬
; ----------------------------------------------------------------------
assume cs :codesg , ds :datasg , ss :stacksg
datasg segment
db 'welcome to masm!' , 0
datasg ends
stacksg segment
db 16 dup ( 0 )
stacksg ends
codesg segment
main: mov ax , datasg
mov ds , ax
mov ax , stacksg
mov ss , ax
mov sp , 16
mov bp , sp
sub sp , 6 ; 以下三个是局部变量,用堆栈保存 翻译成C语言
mov word ptr [bp- 6 ] , 2h ; int cl = 02h
mov word ptr [bp- 4 ] , 3 ; int dl = 3
mov word ptr [bp- 2 ] , 8 ; int dh = 8
push [bp- 2 ] ; 这里用栈传递三个参数 show_str ( cl , dl , dh )
push [bp- 4 ]
push [bp- 6 ]
call show_str
add sp , 12
mov ax , 4c00h
int 21h
show_str: push bp
mov bp , sp
dec word ptr [bp + 8 ] ;( dh- 1 ) * 160 这里是计算行数
mov ax , 160
mul word ptr [bp + 8 ]
mov [bp + 8 ] , ax
dec word ptr [bp + 6 ] ;( dl- 1 ) * 2 这里是计算列数
mov ax , 2
mul word ptr [bp + 6 ]
mov [bp + 6 ] , ax
mov ax , 0b800H ; 设置es :b800H
mov es , ax
mov bx , [bp + 8 ] ; 设置bx,即是偏移地址
add bx , [bp + 6 ]
mov si , 0 ; si记录ds中的偏移
mov di , 0 ; 自然 di是记录es中的偏移了
s: mov cl , ds:[si]
mov ch , 0
jcxz ok ; 发现是0,即到了字符串结尾了
mov es:[bx + di] , cx ; 如果不是结尾那么就拷贝
mov ax , [bp + 4 ]
mov es:[bx + di + 1 ] , ax
add di , 2
inc si
jmp s ; 循环
ok: pop bp
ret
codesg ends
end main
网上有大师传言“汇编应该放在C语言之前学习”,吾等天资愚钝,学了c之后再研究汇编同样是亦趋亦步,私下揣摩如若当初以汇编起步,可能到现在还没入门。看来我等平平小辈还是先学习c再回头研究汇编,C语言基础并不复杂,现在细想,除了指针(其实初学者所遇指针也无非是些数组指针相互变化尔,像指针的内存分配只有到数据结构中才有深入认识),学习过程也该是一马平川的,倘若有较好的c基础,估计入门汇编也不会太难,在寻址,子程序这些概念不会太过于陌生,想对于一个没有任何程序经验的入门者来说,要去理解寻址,子程序恐怕有些困难。一家之言,见笑了