学习IBM-PC汇编程序设计 一书的一个例子中的..几个小问题..

moliliang 2009-06-20 08:11:30
今天去买了本汇编的书( IBM-PC汇编语言程序设计).. 原来看的电子书..翻起来不舒服..

在P147中有这样一个例子..


;数据段 source_buff变量为40个a
data segment
source_buff db 40 dup('a')
data ends

;附加段 dest_buffer 为40个字节的缓冲区
extra segment
dest_buffer db 40 dup(?)
extra ends

;代码段
code segment
main proc far ;main 类似高级语言中的函数名?
assume cs:code, ds:data, es:extra ;将段对应到相应段寄存器

start:
push ds ;将ds数据段压入栈
sub ax,ax ;ax减ax 就是清空?
push ax ;将ax压入栈

;将data的偏移地址放入ds数据寄存器
mov ax,data
mov ds,ax
;将extra的偏移地址放入es附加寄存器
mov ax,extra
mov es,ax
;以下为主要部分
lea si,source_buff ; 将source_buff的偏移地址放入 SI寄存器
;疑惑,SI和DI有着什么样的联系? 一个是源变址寄存器,一个是目的变址寄存器?
lea di,dest_buffer ; 这里是将source_buf和dest_buffer进行关联吗?

cld

mov cx,40 ;cx计数寄存器 计数40 ? 概念有点模糊
rep movsb ;movsb传送字符, rep是置0 ? 这个究竟是什么意思..? 书上说是传送整个字符串
ret ;返回

main endp;main"函数"结束

code ends

end start


有几个问题..
========
push ds ;将ds数据段压入栈
sub ax,ax ;ax减ax 就是清空?
push ax ;将ax压入栈
这三行代码的作用是什么, 我知道是压栈, 问题是他在程序中起到什么样的作用..?
--------
========
lea si,source_buff ; 将source_buff的偏移地址放入 SI寄存器
;疑惑,SI和DI有着什么样的联系? 一个是源变址寄存器,一个是目的变址寄存器?
lea di,dest_buffer ; 这里是将source_buf和dest_buffer进行关联吗?
还是不知道这两行代码在程序中起的作用...?
--------
========

我发现汇编的难点不是那些指令, 而是这些指令组合起来后, 搞不清其中的原理..- -!!! 汇编新手,请大家多多关照..
...全文
111 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuxufeiyang 2009-07-09
  • 打赏
  • 举报
回复
看看
moliliang 2009-07-02
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 gzgzlxg 的回复:]
引用 4 楼 moliliang 的回复:
理解代码上...大家有什么高招..


下面是我以前在别的网站和人吵架时说的其中的一段话:
......其实不管学习什么东西,悟性(即天分)是很重要的,虽说笨鸟先飞早入林,如果鸟笨的连方向都没有了,那是入不了林的。
......很多朋友认为汇编语言不好学,认为自己悟性不够,其实许多时候学不好汇编并不代表这个人笨,往往事实正好相反,我曾经教过别人学汇编语言,我对他们说,“你门学不好汇…
[/Quote]
想太多了?...不够单纯..- -
liwenvv 2009-06-24
  • 打赏
  • 举报
回复
推荐一本书:求伯君《新编深入DOS编程》,那时候感觉就像圣经一样,就看你还能不能找得到。

想学一门编程语言,我的看法是:(1)多看书,多思考,多总结;(2)多动手,多试验;(3)看不懂的地方,在调试器里一步一步跟踪。

熟能生巧,开始不要怕困难,人有惰性,第一步总是很难迈,但一旦迈出去就海阔天空。你平时上班出门、写文档落笔可能都有这种感觉。
gzgzlxg 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 moliliang 的回复:]
理解代码上...大家有什么高招..
[/Quote]
下面是我以前在别的网站和人吵架时说的其中的一段话:
......其实不管学习什么东西,悟性(即天分)是很重要的,虽说笨鸟先飞早入林,如果鸟笨的连方向都没有了,那是入不了林的。
......很多朋友认为汇编语言不好学,认为自己悟性不够,其实许多时候学不好汇编并不代表这个人笨,往往事实正好相反,我曾经教过别人学汇编语言,我对他们说,“你门学不好汇编不是太笨了,而是太聪明了”。大家要知道,我们人类的思维能力非常了不起,比如一个儿童,看电影,会问, “爸爸这人是好人坏人”,我想很多父亲可能很难回答这个问题,为什么?因为许多人是不能用一个好或坏来定义的,他可能是70%的坏人加30%的好人,如果这个儿童去学汇编,肯定比他父亲强,因为汇编的思维方式就是好人坏人。所以在学习汇编语言时你要回到童年,多想想什么是好人坏人的问题,也许你会发现,汇编语言原来这么容易学。
那么怎样才算学好汇编了,学英文的朋友都知道,当你能用英文来思考问题时,那么你的英文就真正的过关了。同样,如果你能用汇编语言来思考你要解决的问题,那么你的汇编就过关了。很难?难不难就看你是不是有心人了,多锻炼就习惯成自然了。(等你学好了汇编语言,你可不要骂我,我怎么感觉越来越笨了,不,我说,是回到童年了)
gzgzlxg 2009-06-22
  • 打赏
  • 举报
回复
“如果我想比较深入地见识下DOS(不是只知道几个DOS命令),有什么经典的教材或资料可以基本引领我深入一下”

早年通读过DOS操作系统的源代码,那本书丢失了(书名也忘了,整大本的源代码)。
现在手头只有一本清华大学出版社1993年出版的【PC软硬件技术资料大全】,这本书什么都有,但也什么都没有说清楚。不过对我比较实用。
这两本书,大学的图书馆应该能找到。
因为不是电子资料,所以无法和大家共享。
nanlingcg 2009-06-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 moliliang 的回复:]
理解代码上...大家有什么高招..
[/Quote]
没有高招,只有实学。
其实楼主贴的程序就是设了一个DS段里面一字节形式连续放了40个“a”,又建了个ES段,搞了40个空白字节,程序一开始就把PSP的首地址保存了,然后把2个变量地址传给SI和DI,方向标志置0(增),设定记数器为40以REP和 MOVSB连用,连续以[SI]为源,[DI]为目的,执行CX里的40次字节传送,同时SI和DI每循环1次就自增1。循环完了就返回,IP指向程序入口压栈的PSP首地址。从gzgzlxg大超侠提供的PSP结构来看,首地址那有个INT 20H指令(DOS中断返回),于是就回DOS了。
嘿嘿,以前我以为一个RET把指令指针指向PSP首地址是把IP跳出程序入口之前就回DOS了,原来那还有个INT 20H啊?
真的很感谢gzgzlxg超侠的无言指导。
真的很感谢!
nanlingcg 2009-06-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 gzgzlxg 的回复:]
“如果我想比较深入地见识下DOS(不是只知道几个DOS命令),有什么经典的教材或资料可以基本引领我深入一下”

早年通读过DOS操作系统的源代码,那本书丢失了(书名也忘了,整大本的源代码)。
现在手头只有一本清华大学出版社1993年出版的【PC软硬件技术资料大全】,这本书什么都有,但也什么都没有说清楚。不过对我比较实用。
这两本书,大学的图书馆应该能找到。
因为不是电子资料,所以无法和大家共享。

[/Quote]
谢谢。谢谢指点。
虽无法共享,但却指出了光亮,总比我自己无目标探求要强。
谢谢!
wb378499835 2009-06-21
  • 打赏
  • 举报
回复
3楼说的不错,学习了
nanlingcg 2009-06-20
  • 打赏
  • 举报
回复
一直都想知道PSP究竟里面是哪些信息在里面,今天终于略睹圣颜。
3楼出手不凡,厉害!
随便向3楼gzgzlxg超侠请教下:如果我想比较深入地见识下DOS(不是只知道几个DOS命令),有什么经典的教材或资料可以基本引领我深入一下,敢问gzgzlxg超侠您手头有没有可以通过网络传递的电子教材或资料,能惠及下我。就是说指点个网站给我或推荐一点可以获得的资料给我。。。
如果您手头上就有可以通过网络传发的资料而您又愿意发给我那就更好不过了。。。
期待gzgzlxg超侠的回音。
我的邮箱:nanlingcg@126.com
先谢过gzgzlxg侠!
goodider 2009-06-20
  • 打赏
  • 举报
回复
其实还是要真的理解PUSH和POP的原理。那样就容易多了。
BAYNPU 2009-06-20
  • 打赏
  • 举报
回复
这是个简单的字节传送程序它是把源串的数据(source_buff)传送到目的串中(dest_buffer).

rep :每执行一次串指令,CX减1;直到=0,重复执行结.

MOVSB ;字节串传送:ES:[DI]←DS:[SI],SI←SI±1,DI←DI±1.

也可以改为字传送:MOVSW ;字串传送:ES:[DI]←DS:[SI],SI←SI±2,DI←DI±2.

mov cx,40;这是个设置字节传送,如果是字传送可以改为20次.
moliliang 2009-06-20
  • 打赏
  • 举报
回复
理解代码上...大家有什么高招..
gzgzlxg 2009-06-20
  • 打赏
  • 举报
回复
dos系统启动后,ds指向PSP结构(程序头,相对于windows系统的pe头),psp结构如下:

+-------+----------+-------------------+----------------------------------------+
|Offset | Length | Name | Description |
+-------+----------+-------------------+----------------------------------------+
|0(0) | word |pspInt20 |Int 20H instruction |
+-------+----------+-------------------+----------------------------------------+
|2(2) | word |pspNextParagraph |End of memory allocation block |
+-------+----------+-------------------+----------------------------------------+
|4(4) | byte | |RESERVED |
+-------+----------+-------------------+----------------------------------------+
|5(5) | 5 byte |pspDispatcher |Far call to DOS function request handler|
+-------+----------+-------------------+----------------------------------------+
|A(10) | dbl word |pspTerminateVector |Int 22H terminate handler address |
+-------+----------+-------------------+----------------------------------------+
|E(14) | dbl word |pspControlCVectpr |Int 23H Ctl+C handler address |
+-------+----------+-------------------+----------------------------------------+
|12(18) | dbl word |pspCritErrorVector |Int 24H Critical Error handler address |
+-------+----------+-------------------+----------------------------------------+
|16(22) | 11 word | |RESERVED |
+-------+----------+-------------------+----------------------------------------+
|2C(44) | word |pspEnvironment |Segment address of environment block |
+-------+----------+-------------------+----------------------------------------+
|2E(46) | 23 word | |RESERVED |
+-------+----------+-------------------+----------------------------------------+
|48(72) | 16 byte |pspFCB_1 |First 16 bytes of first default FCB |
+-------+----------+-------------------+----------------------------------------+
|58(88) | 16 byte |pspFCB_2 |First 16 bytes of secpmd defai;t FCB |
+-------+----------+-------------------+----------------------------------------+
|68(104)| dbl word | |RESERVED |
+-------+----------+-------------------+----------------------------------------+
|6C(108)|128 bytes |pspCommandTail |Command-line parameters |
+-------+----------+-------------------+----------------------------------------+

push ds
sub ax, ax
push ax
...
...
retf

相当于调用 int 20H
push
goodider 2009-06-20
  • 打赏
  • 举报
回复
push ds ;将ds数据段压入栈
sub ax,ax ;将ax清0
push ax ;将ax(0)压入栈
这三行代码的目的是最后ret的时候返回到ds:0地址处,使程序退出。这种退出程序的方法不好,应该用
mov ax,4c00h
int 21h
这样退出。
着两段效果一样。不过一般16位编程都用后面那种。
后一个问题1楼已经回答了。
cnzdgs 2009-06-20
  • 打赏
  • 举报
回复
push ds ;将ds数据段压入栈
sub ax,ax ;将ax清0
push ax ;将ax(0)压入栈
这三行代码的目的是最后ret的时候返回到ds:0地址处,使程序退出。这种退出程序的方法不好,应该用
mov ax,4c00h
int 21h
这样退出。

movsb指令是把ds:si指向的内存数据复制到es:di指向的内存,在执行movsb之前通常用lea指令初始化si、di。

21,500

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧