免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 12839 | 回复: 20
打印 上一主题 下一主题

求助:一个最简单的汇编程序~~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-05 21:19 |只看该作者 |倒序浏览
  1. .data
  2.     msg:.ascii "Hello, world!\\n"
  3.     len=5

  4. .text
  5. .globl _start
  6. _start:
  7.     movl $len,%edx
  8.     movl $msg,%ecx
  9.     movl $1,%ebx
  10.     movl $4,%eax
  11.     int  $0x80

  12.         pushl $12
  13.         movl $12,%ebx
  14.         movl $1,%eax
  15.         int  $0x80
复制代码


本来是想打印一个字符串,但运行后什么都没有。
我郁闷了一下午了。这个代码是在网上的教程里找的,按说语法因该没问题啊,不然也编译不过去。
我看了freebsd的开发手册,上面有说汇编的,但用例都是intel语法的,照它上面的例子来看,好像系统调用的传参除了调用号都是通过堆栈传的,我也照那个改过,就是把上面的movl全改成pushl的,但是也没有反应!实在搞不懂了,请高手救救命吧!

[ 本帖最后由 雨丝风片 于 2006-5-11 08:38 编辑 ]

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
2 [报告]
发表于 2006-04-05 23:37 |只看该作者
assume the file name is msg.s

  1. .data
  2.     msg: .ascii "Hello, world!\n"
  3.     len = . - msg
  4. .text
  5. .globl _start
  6. _start:
  7.     pushl $len
  8.     pushl $msg
  9.     pushl $1
  10.     movl $4, %eax
  11.     pushl %eax
  12.     int  $0x80

  13.     pushl $0
  14.     movl $1,%ebx
  15.     pushl %eax
  16.     int  $0x80
复制代码
cc -s -c msg.s
ld -s -o msg msg.o
./msg

论坛徽章:
0
3 [报告]
发表于 2006-04-06 10:01 |只看该作者
楼上的太强了,偶像啊!!!
原来这个调用号既要放到eax里,还要放到堆栈里啊,bsd干嘛搞得这么复杂呢

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
4 [报告]
发表于 2006-04-06 20:02 |只看该作者
原帖由 wellbye 于 2006-4-6 10:01 发表
楼上的太强了,偶像啊!!!
原来这个调用号既要放到eax里,还要放到堆栈里啊,bsd干嘛搞得这么复杂呢


偶像?呕像吧
这个例子是developer's handbook(简称dh)里的。
由于FreeBSD采用的是C语言的调用方式来访问中断,也就是说需要下面的代码序列(dh里面也有讲述,只是很隐晦)

  1. xx:
  2.    int $0x80
  3.    ret

  4. yy:
  5.    pushl zz
  6.    pushl zz
  7.    movl n, %eax   系统调用号
  8.   call  xx
  9.    add %esp,$8 恢复堆栈,ret会弹出eip,所以只需要跳过上面两个参数2*4=8字节。
复制代码


虽然这样的调用方式需要堆栈的介入,并且看起来比Linux采用的寄存器传递方式慢(因为有可能的访存操作)
但是,得到的好处是可移植性很好(因为C语言本身是移植性很强,因此才采用C语言的调用方式)

而在上面写法省略call时,情况需要调整。(因为call/ret指令对的指令周期比movl pushl长)
call的时候会在堆栈压入eip作为返回地址,为了满足这样的调用栈桢,我们就必须伪造一个eip。因为我们不使用这个eip(伪造的嘛),所以pushl %eax 这里的%eax可以是任何值,只要是32位的双字,仅仅作为填充物。(这也是dh原文在pushl边上解释的意义。)
add %esp,$12  没有了ret指令,所以堆栈上的eip不会弹出,恢复堆栈时需要算上它,就是3*4=12字节。

[ 本帖最后由 gvim 于 2006-4-6 20:07 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2006-04-06 23:21 |只看该作者
不服不行,受教了

论坛徽章:
0
6 [报告]
发表于 2006-04-07 10:19 |只看该作者
哎,我看书就是不仔细呀,gvim 一说,我就找到那一章了,佩服佩服!
不过还是有点小问:
call的时候不是把cs和eip一起丢到栈里的吗,为什么这里按普通方式调用时填充堆栈只需一个32位双字了?加上cs的话,应该再来一个双字的吧?

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
7 [报告]
发表于 2006-04-07 23:28 |只看该作者
段内call 不需要保存cs

论坛徽章:
0
8 [报告]
发表于 2006-04-08 08:02 |只看该作者
原来不熟悉这个过程,昨天恶补了一下int0x80_syscall和syscall的代码,原来是因为FreeBSD的syscall函数首先会取得int 80h之前的esp,再跳过先于esp压栈的ss:

params = (caddr_t)frame.tf_esp + sizeof(int);

然后再跳过一个假定其存在的“eip”:

params += sizeof(int);

这才让params指向了我们在int 80h之前压栈的本次系统调用的参数。也就是说,是因为syscall函数是按堆栈上存在eip空间的假定来写的,于是,我们如果用call来写系统调用,自然满足这个假定,否则,就需要“填充”一下,免得syscall函数在找系统调用参数的时候找错了地方。

本来还想把这个过程的前因后果做个详细的学习笔记的,结果把wheelz的【FreeBSD 5内核源代码分析之系统调用过程】翻来一看,全在里面了。真是“眼前有景题不得,wheelz大文在上头”啊。

也怪自己读书不仔细,人家开发手册的系统调用部分的开篇第一段就讲:“Further, although the kernel is accessed using int 80h, it is assumed the program will call a function that issues int 80h, rather than issuing int 80h directly.”当初看这片文档的时候就直奔下面的汇编代码示例去了,却没有好好地去读读这句话,惭愧惭愧!

只是FreeBSD的syscall为何要做这个假定?反正都是规矩,用户程序的写法自然是跟着syscall的写法走的。不知有什么历史原因没有。

论坛徽章:
0
9 [报告]
发表于 2006-04-08 09:52 |只看该作者
原帖由 雨丝风片 于 2006-4-8 08:02 发表
只是FreeBSD的syscall为何要做这个假定?反正都是规矩,用户程序的写法自然是跟着syscall的写法走的。不知有什么历史原因没有。...


开发手册上提到了一句这样做的原因,看来主要还是一个良好编程风格的问题:

This is a very clean and portable way of coding. If you need to port the code to a UNIX system which uses a different interrupt, or a different way of passing parameters, all you need to change is the kernel procedure.

论坛徽章:
0
10 [报告]
发表于 2006-04-24 09:23 |只看该作者
mooling@localhost$ cc -s -c msg.s
mooling@localhost$ ld -s -o msg msg.o
mooling@localhost$ ./msg
Hello, world!
Segmentation fault: 11 (core dumped)
mooling@localhost$
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP