LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 895|回复: 5

linux 内联汇编问题求助!

[复制链接]
发表于 2005-6-3 10:40:49 | 显示全部楼层 |阅读模式
试图用汇编指令打开一个字符设备模块,代码如下:

{
    __asm__("mov  %0,%%ecx":"r"(O_RDWR));
    __asm__("mov  %0,%%ebx":"r"("mydeivce"));
    __asm__("movl $0x05,%%eax"::"eax");
    __asm__("int $0x80");
    __asm__("mov  %%eax,%0":"=r"(fd));
}            

mydevice是字符设备名
编译出错如下:

[root@sleepjeep code_3]# gcc -c -I/usr/src/linux-2.4.20-8/include usystime_3.c
usystime_3.c: In function `main':
usystime_3.c:43: invalid lvalue in asm statement
usystime_3.c:45: parse error before ')' token
usystime_3.c:43: output operand constraint lacks `='
usystime_3.c:44: output operand constraint lacks `='
usystime_3.c:44: warning: modification by `asm' of read-only location

什么问题呢?
高手指点一下吧,先谢了!
发表于 2005-6-3 15:41:30 | 显示全部楼层
问题比较多

1:调用int 0x80,对于寄存器的调用不能随便使用!第几个参数用那个寄存器是有规定的!

2:没有输出寄存器也要写上 ":"
      __asm__("mov %0,%%ecx":"r"(O_RDWR));
     应该这样写
   __asm__("mov %0,%%ecx"::"r"(O_RDWR));

3:__asm__("mov %0,%%ebx":"r"("mydeivce"));你这里的mydeivce是什么意思呢!
   如果它是函数名,你不能加" "的,加了之后是什么呢?你想想看!

4:按惯例,输出寄存器应该用eax

5:at&t汇编,操作码明确对应操作数
     __asm__("mov %%eax,%0":"=r"(fd));这里用的是eax,而操作码用的却是'mov'

可能还有其他没看出来的问题!我这没有linux,没有办法调
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-4 09:22:13 | 显示全部楼层
首先感谢2楼的意见!
这段代码原是 计算机工程与应用 杂志中一篇论文的代码,详见计算机工程与应用 2004.4 P119。
主要目的是在不发生堆栈切换的情况下打开一个字符设备文件。
2楼提到的问题我在周一才能调试,谢谢帮忙!请继续关注
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-6 15:10:04 | 显示全部楼层
修改后代码如下,请指正
    char mydc[]="mydevice";
    int fd;
    __asm__("movl  %0,%%ecx"::"r"(O_RDWR));
    __asm__("movl  %0,%%ebx"::"r"(&mydc));                    //赋设备文件名地址给ebx(可能有误)
    __asm__("movl %0,%%eax"::"r"(0x05));                       //赋系统调用号给eax   
    __asm__("int $0x80");
    __asm__("mov  %%eax,%0":"=r"(fd));                         //返回执行结果
回复 支持 反对

使用道具 举报

发表于 2005-6-6 15:55:11 | 显示全部楼层
#ifndef __NR_open
#define __NR_open 5
#endif

#ifndef O_RDWR
#define O_RDWR 02
#endif

int open_device(const char * devicename)
{
        register int res;
        __asm__("int $0x80"
                :"=a" (res)
                :"0" (__NR_open),"b" (devicename),"c" (O_RDWR));
        if (res>=0)
                return res;
        return -1;
}
上面的代码我没有调试(因为,我这没有linux)!
你调试看看可否!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-7 14:32:39 | 显示全部楼层
非常感谢
问题解决.

问题在文件名上,加上路径后解决

同时gotop2004兄的程序更加精炼,在此致以崇高谢意!多谢指教!

如有问题还请继续指点
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表