书中demo求解

不担心 2016-03-20 02:39:18
section .bss
Buff resb 1

section .data

section .text
global _start

_start:
nop

Read: mov eax,3 l
mov ebx,0
mov ecx,Buff
mov edx,1
int 80h

cmp eax,0
je Exit

cmp byte [Buff],61h
jb Write
cmp byte [Buff],7Ah
ja Write

sub byte [Buff],20h

Write: mov eax,4
mov ebx,1
mov ecx,Buff
mov edx,1
int 80h
jmp Read

Exit: mov eax,1
mov ebx,0
int 80H

这个是书本中的一个例子,功能是读入一个文本,然后将所有的小写转换为大写,运行非常正常,没有问题.
我不明白的是在read标签处通过
mov ecx,Buff ; Pass offset of the buffer to read to
mov edx,1 ; Tell sys_read to read one char from stdin
命令读入一个字节,那么在write标签处jmp 到read处,再次执行的时候为什么会读取下一个字节呢?buff的地址并没有变,中间也没有计算器指明偏移量,应该读取还是原来的那个字符才对,请大大们帮忙解释一下.谢谢!
...全文
207 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
fornetuse123 2016-03-23
  • 打赏
  • 举报
回复
上面的reand子程序 代码循环代码错误了,临时缓冲区基址因该换个寄存器不用ecx就好了。反正就是那么个意思。
fornetuse123 2016-03-23
  • 打赏
  • 举报
回复
终于想明白了, int80应该是这样的代码: cmp ebx,0 je readentry cmp ebx,1 je writeentry iret readentry:push ecx push edx call readstdin pop edx pop ecx iret writeentry: push ecx push edx call writestndout pop edx pop ecx iret 也就是说int80还需要调取一个读或者写子程序。 readstndin是这样的。 read:push ecx move ecx,edx ;将需要读入临时缓冲区的字节数用来计数循环,因为临时缓冲区基地址保存在ecx中,所以要 先入栈保护 move eax,[bx ] ;bx为标准输入缓冲区基地址 cmp eax,0 ;0为字符串结束标志 je exit pop ecx mov byte ptr[ecx],eax ;往临时缓冲区写数据 inc ecx ;临时定义缓冲区指针移位 inc bx ;标准输入缓冲区基地址指针移位 loop read exit: ret 也就是说,int80只是用来调度读写操作和给相应子程序传递参数的,而真正的读或者写子程序负责往临时缓冲区读或者写数据,并调整指针。
不担心 2016-03-23
  • 打赏
  • 举报
回复
fornetuse123 2016-03-22
  • 打赏
  • 举报
回复
昨晚我又想了想 如果缓冲区是堆栈的话,就简单实现了。 mov ebx,0 ;从原始文件stdin的缓冲区,告诉int80子程序ss段基址和sp指针 mov ecx,Buff ;读取内容存放到buff mov edx,1 ;从从原始文件stdin的缓冲区当前指针处读取1个字节,存放到buff int 80h 这样int80子程序只要根据edx中的数字进行计数循环,pop edx中的数字次到buff开始的0+edx中的数字个字节内存中去(假设buff内存区足够大) 这样,应用程序就不用申请系统对缓冲区进行管理,大大降低系统开销和效率。 但是,有个问题,缓冲区的这个堆栈是不是专用的呢?如果不是专用,那么在另外的线程也使用该堆栈时,如果执行了push或pop操作,那么,现在的线程再读取到的堆栈内容其实不是想需要的。这怎么处理
赵4老师 2016-03-21
  • 打赏
  • 举报
回复
在DosBox下使用TurboDebug单步调试。 bc++3.1 http://download.csdn.net/source/2805028
  • 打赏
  • 举报
回复
程序没有问题。 linux int 80h是系统调用,eax=3是sys_read,ebx=file descriptor(0---stdin,1---stdout),eax=4是sys_write。stdin、stdout是流式设备(DOS、Windows中叫字符设备),不需要也不能显式移动文件指针,每次访问后会自动移动。
fornetuse123 2016-03-21
  • 打赏
  • 举报
回复
我明白这段代码的意思了,楼主你大概这段代码少抄了一段吧 那就是Tell sys_read to read one char from stdin中的sadin这一段 这段程序的功能因该是你在键盘中输入一个非0字符,每次只能输一个,你输多了也没用,程序每次只显示一个。 如果输入0,程序就结束了 如果输入不是大小写字母,程序直接显现该字符 如果输入是小写字母,程序转换为大写字母输出。 楼主你看书能不能仔细点,书中有说输出一段文本字符么?另外标准输入设备那一段,你忘记抄也不对吧
fornetuse123 2016-03-21
  • 打赏
  • 举报
回复
还有这句 cmp eax,0 je Exit 那不是这个程序死循环了么。我怎么看永远不会eax=o呢
不担心 2016-03-21
  • 打赏
  • 举报
回复
我也觉得应该是系统内部有个读取缓冲区的指针,每次读取固定长度的内容之后,指针就停留在最后读取的地方,之后接着往后读取
可能是这样
fornetuse123 2016-03-21
  • 打赏
  • 举报
回复
引用 1 楼 zara 的回复:
每次处理,就是一个字符,总是放到 buff 这里的;后面的字符会把前面的覆盖了,所以程序的最后,程序里是没有完整的输入的字符串的,即便是在屏幕上显示了。
这段代码我也有同样疑问呀?即便覆盖原来,那它读原buffde时候,没有增加偏移量,那不是还读的同一个位置么 ?那显示的不就是同一个字么这次大写,下次小写循环了。怎么会读取一段字符的
zara 2016-03-21
  • 打赏
  • 举报
回复
每次处理,就是一个字符,总是放到 buff 这里的;后面的字符会把前面的覆盖了,所以程序的最后,程序里是没有完整的输入的字符串的,即便是在屏幕上显示了。
fornetuse123 2016-03-21
  • 打赏
  • 举报
回复
不对,还应该是系统来管理缓冲区指针,否则如果缓冲区是链队列逻辑结构的话,int80好像没那么大能力。 应该就是:缓冲区内容在被读取后,指针被系统移动相应字节位置,即缓冲区内容不是静态不变的
fornetuse123 2016-03-21
  • 打赏
  • 举报
回复
实际上,读取原始文件stdin的缓冲区的参数中,edx的取值范围是1-缓冲区长度,如果int80中没有功能为将point-> stdin头指针指向->next这样的语句,他怎么实现读取任意长度的缓冲区字节内容了?在这里,系统在文件被读入缓冲区后,应该已经将控制权交还给应用程序,所以最大的可能就是:int80有自动更改缓冲区指针的功能 Read: mov eax,3 l mov ebx,0 ;从原始文件stdin的缓冲区 mov ecx,Buff ;读取内容存放到buff mov edx,1 ;从从原始文件stdin的缓冲区当前指针处读取1个字节,存放到buff int 80h
fornetuse123 2016-03-21
  • 打赏
  • 举报
回复
根据几位大神的解说,加上百度,不知道我这样理解的对不对: 你说你是将一个原始文件读入,然后转换为大写输出到另一个文件了 这个程序的作用是这样的,首先一个重点:系统读写一个文件都要先创建一个缓冲区, 这里,程序先从原始文件stdin的缓冲区里取1个字节的内容,存放到你定义的一个字节的buff内存中,这里buff内存和原始文件stdin的缓冲区是两块不同的内存,但是这块buff内存是写大写输出到另一个文件的缓冲区。 当你从原始文件stdin的缓冲区里取1个字节后,Read: mov eax,3 l mov ebx,0 ;从原始文件stdin的缓冲区 mov ecx,Buff ;读取内容存放到buff mov edx,1 ;从从原始文件stdin的缓冲区当前指针处读取1个字节,存放到buff int 80h 系统会将原始文件stdin的缓冲区里的内存指针指向下一个字节,除非你读完了缓冲区最后一个字节,这时,应该是一个空指针。其实我感觉最大的可能是,int80这个中断子程序里就含有功能为将point-> stdin头指针指向->next这样的语句,否则不可能实现读写文件。但是我们看不到int80内部代码 我们两个的误区在于:认为自己定义的buff是原始文件stdin的缓冲区,其实它只不过是每次从原始文件stdin的缓冲区读取了一个字节而已。相应,他每次向另一个文件写入一个字节。
  • 打赏
  • 举报
回复
stdin是标准输入,典型例子就是键盘。
  • 打赏
  • 举报
回复
Read: mov eax,3 mov ebx,0 mov ecx,Buff mov edx,1 int 80h 从stdin读一个字符存在Buff里。stdin就象水龙头,每次打开放出来的都是不同的水(当然也可能没水),是系统在内部维护一个缓冲区,每读一次就取走一部分,系统会自动移动文件指针。
不担心 2016-03-21
  • 打赏
  • 举报
回复
引用 4 楼 fornetuse123 的回复:
我明白这段代码的意思了,楼主你大概这段代码少抄了一段吧 那就是Tell sys_read to read one char from stdin中的sadin这一段 这段程序的功能因该是你在键盘中输入一个非0字符,每次只能输一个,你输多了也没用,程序每次只显示一个。 如果输入0,程序就结束了 如果输入不是大小写字母,程序直接显现该字符 如果输入是小写字母,程序转换为大写字母输出。 楼主你看书能不能仔细点,书中有说输出一段文本字符么?另外标准输入设备那一段,你忘记抄也不对吧
section .bss
	Buff resb 1

section .data

section .text
	global _start

_start:
	nop            ; This no-op keeps the debugger happy

Read:	mov eax,3      ; Specify sys_read call
	mov ebx,0      ; Specify File Descriptor 0: Standard Input
	mov ecx,Buff   ; Pass offset of the buffer to read to
	mov edx,1      ; Tell sys_read to read one char from stdin
	int 80h        ; Call sys_read

	cmp eax,0	; Look at sys_read's return value in EAX
	je Exit		; Jump If Equal to 0 (0 means EOF) to Exit
			; or fall through to test for lowercase
	cmp byte [Buff],61h  ; Test input char against lowercase 'a'
	jb Write	; If below 'a' in ASCII chart, not lowercase
	cmp byte [Buff],7Ah  ; Test input char against lowercase 'z'
	ja Write	; If above 'z' in ASCII chart, not lowercase
			; At this point, we have a lowercase character
	sub byte [Buff],20h  ; Subtract 20h from lowercase to give uppercase...
			; ...and then write out the char to stdout
Write:  mov eax,4	; Specify sys_write call
	mov ebx,1	; Specify File Descriptor 1: Standard output
	mov ecx,Buff	; Pass address of the character to write
	mov edx,1	; Pass number of chars to write
	int 80h		; Call sys_write...
	jmp Read	; ...then go to the beginning to get another character

Exit:	mov eax,1	; Code for Exit Syscall
	mov ebx,0	; Return a code of zero to Linux
	int 80H		; Make kernel call to exit program
这是完整的带注释的代码,我不知道你说的漏了什么 这段代码我编译运行过了,没问题,功能是是读取一个文本文件,将所有小写转成大写保存到另一个文件 ./uppercase1 < xxx.txt > xxxUp.txt
不担心 2016-03-21
  • 打赏
  • 举报
回复
引用 5 楼 DelphiGuy 的回复:
程序没有问题。 linux int 80h是系统调用,eax=3是sys_read,ebx=file descriptor(0---stdin,1---stdout),eax=4是sys_write。stdin、stdout是流式设备(DOS、Windows中叫字符设备),不需要也不能显式移动文件指针,每次访问后会自动移动。
虽然我不懂,但是我觉得你说的是对的,能详细解释一下吗? 调用了80中断后 mov ecx,Buff mov edx,1 这两句为什么会读取后面一个字节?
1.本书附源代码共计381个,其运行环境如下: IE 5或更高版本 Mozilla Firefox 1.5.0.3或更高版本 服务器采用IIS5.1 或以上版本 数据库使用MS Access 2000以上 2.本书所附光盘实例代码: 第1章(\第1章) 查看1.2.htm中noscript显示效果的方法如下: 1.将该实例复制到C:\Inetpub\wwwroot下; 2.选择浏览器的“工具”-“安全”-“本地Intranet”-“自定义级别”-“活动脚本”中选用“禁用”单选框 3.在浏览器中输入下述地址:http://localhost/1.2.htm • 1.1.htm 多段代码相互调用 • 1.2.htm <script>与的内容 • 16.21.htm 改变页面样式 • blue.css 16.21.htm用到的样式文件 • red.css 16.21.htm用到的样式文件 • green.css 16.21.htm用到的样式文件 第17章(\第17章) • 17.1.htm Form对象测试 • 17.2.htm 基本按钮 • 17.3.htm button按钮 • 17.4.htm 文本域 • 17.5.htm 文本区 • 17.6.htm 限制输入长度的文本区 • 17.7.htm 限制输入长度的文本区之二 • 17.8.htm 复选框与单选按钮 • 17.9.htm 验证输入内容是否为空 • 17.10.htm 验证输入内容是否为空 • 17.11.htm 混合表单验证 • 17.12.htm 按键屏蔽 • 17.13.htm 屏蔽表单域 • 17.14.htm 动态表单 第18章(\第18章) • 18.1.htm 复选框 • 18.2.htm 单选按钮 • 18.3.htm 复选框与单选按钮的组合使用 • 18.4.htm 使用elements[]数组 • 18.5.htm 选择控件 • 18.6.htm 多项选择控件 • 18.7.htm 级联选择控件 第19章(\第19章) • 19.1.htm 友情链接 • 19.2.htm 需要确认的友情链接 • 19.3.htm 渐显效果的下拉菜单 • 19.4.htm 模拟系统菜单 • 19.5.htm 图片显示窗口 • 19.6.htm 远程控制菜单 • 19.7.htm 滑动菜单 • 19.8.htm 左键弹出式菜单 • 19.9.htm 浮动菜单 • 19.10.htm 导航式菜单 第20章(\第20章) • 20.1.htm 显示浏览器名称与版本号 • 20.2.htm 显示浏览器名称(改进章) • 20.3.htm JavaScript支持检测1 • 20.4.htm JavaScript支持检测2 • 20.5.htm JavaScript对象检测 • 20.6.htm Screen对象 • 20.7.htm 获取浏览器窗口大小 • 20.8.htm 字号随浏览器窗口大小而改变 • 20.9.htm 对代码20.8的改写 • 20.10.htm 在网页中有选择地显示图片 • 20.11.htm 客户端性能检测 • 20.12.htm 浏览器按键模拟 • 20.13.htm 修改Mozilla用户主页 • 20.14.htm 修改IE用户主页 第21章(\第21章) • 21.1.htm 编码与解码 • 21.2.htm Cookie值被覆盖 • 21.3.htm Cookie分析 • 21.4.htm 用Cookie保存定制样式 • 21.5.htm DHTML行为 第22章(\第22章) • 22.1.htm 通过单击按钮来改变图像 • 22.2.htm 随机显示不同图像 • 22.3.htm 结构化图形控件 • 22.4.htm 图像定位示例 • 22.5.htm 在IE中拖动图像 • 22.6.htm 按钮翻转示例 • 22.7.htm 跟随屏幕移动的图片 • 22.8.htm 多幅图片滚动显示 • 22.9.htm 图片的左右循环飘动 • 22.10.htm 图片的渐隐渐显 • 22.11.htm 不停闪烁的图片 • 22.12.htm 图片倒映 第23章(\第23章) • 23.1.htm 简单过渡 • layerlib.js JavaScript外部文件 • 23.3.htm 目标翻转 • 23.4.htm 运动图像 • 23.5.htm 随机图像 • 23.6.htm 动画效果 • 23.7.htm Sequencer控件 • 23.8.htm Path控件 • 23.9.htm 永远居中的背景图片 • 23.10.htm 随机显示的背景图片 • 23.11.htm 垂直滚动公告板 • 23.12.htm 类似Flash的字幕效果 • 23.13.htm 地震效果 第24章(\第24章) • MyApplet.txt 简单的Java Applet源程序 • 24.2.htm 在JavaScript中访问Java Applet • 24.3.htm 简单的Flash插件 • 24.4.htm mimeTypes[]数组 • 24.5.htm 使用mimeTypes[]检测支持的媒体类型 • 24.6.htm 使用navigator.plugins[][]列举所有Flash MIME类型 • 24.7.htm 列举plugins[]数组的内容 • 24.8.htm 简单的Flash播放控制器 • 24.9.htm ActiveX控件示例 • 24.10.htm 使代码兼容多种浏览器 • 24.11.htm Flash 播放控制器(ActiveX) 第25章(\第25章) • 25.1.htm 单向通信中的Image • 25.2.htm JavaScript向服务器发送RPC • 25.3.htm 动态内容 • 25.4.htm 中的单词拼写检查 • 25.5.htm 内联框架 第26章(\第26章) 1.查看书中图26.9的效果的方法: 用记事本打开26.5.xml,找到第二行,内容如下: 将两端的去掉并保存该文档后,用IE打开,就可看到图26.9所示的效果。 2.查看书中图26.10的效果的方法: 用记事本打开26.5.xml,找到第3行,内容如下: 将两端的去掉并保存该文档后,用IE打开,就可看到图26.9所示的效果。 3.要查看书中图26.11的效果,须连接Internet。 • 26.1.xml XML文档的例子 • 26.2.xml 包含DTD及其实例的XML文档 • 26.3.xml 要转换的XML文档 • test.xsl 转换XML文档的模板文件 • 26.5.xml 更复杂的要转换的XML文档 • staff.xsl XSL样式表 • staff.css CSS样式表 • 26.8.xml 使用了MathML的XML文档 • 26.9.htm 显示XML文档根结点 • 26.10.htm 使用Jscript与DOM直接操作XML • 26.11.xml 使用Mozilla直接操作XML • 26.12.js 使用Mozilla直接操作XML用到的js文件 • 26.13.htm IE XML数据岛应用 • 26.14.htm IE XML数据岛 • 26.15.rss 简单的rss文件 • 26.16.htm 简单的rss阅读器 第28章(\第28章) • 28.1.htm 显示当前时间 • 28.2.htm 显示当前日期和星期 • 28.3.htm 显示日期、时间和星期 • 28.4.htm 分时段问候 • 28.5.htm 以数字图片来显示时间 • 28.6.htm 显示世界不同地区的当前时间 • 28.7.htm 总是悬浮的时钟 • 28.8.htm 简单的加减乘除运算 • 28.9.htm 能进行四则混合运算的计算器 • 28.10.htm 在表单中显示打字效果 • 28.11.htm 随页面刷新更换页面背景 • 28.12.htm 随页面刷新显示不同图片 第29章(\第29章) • 29.1.htm 汉诺塔问题求解 • 29.2.htm 位置固定的对联广告 • 29.3.htm 随页面滚动的对联广告 • 29.4.htm 循环滚动的多幅广告 • css.css 代码29.4用到的样式文件 • 29.6.htm 用JavaScript实现级联选择 • ajax_server.asp 使用ASP访问demo数据表 • ajax.htm 使用ajax实现级联选择 第30章(\第30章) 代码说明:本章实现了一个ASP留言板程序,程序需要在IIS环境下运行。 • index.asp 留言板主程序 • guestbook.mdb 留言板数据库程序 • images\ 留言板使用的图像文件目录

21,459

社区成员

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

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