简体   繁体   English

包装器函数的内联汇编器由于某些原因无法正常工作

[英]Inline Assembler for wrapper function doesn't work for some reason

I'm trying to write a wrapper function for read() system call , using asm volatile , but it won't work , since the res doesn't change its value . 我正在尝试使用asm volatile为read()系统调用编写一个包装函数,但由于res不会更改其值,因此它不起作用。

Here's the code : 这是代码:

ssize_t my_read(int fd, void *buf, size_t count)

{

      ssize_t res;

      __asm__ volatile(
        "int $0x80"        /* make the request to the OS */
        : "=a" (res),       /* return result in eax ("a") */
          "+b" (fd),     /* pass arg1 in ebx ("b") */
          "+c" (buf),     /* pass arg2 in ecx ("c") */
          "+d" (count)      /* pass arg3 in edx ("d") */
        : "a"  (5)          /* passing the system call for read to %eax , with call number 5  */
        : "memory", "cc"); /* announce to the compiler that the memory and condition codes have been modified */

      /* The operating system will return a negative value on error;
       * wrappers return -1 on error and set the errno global variable */

      if (-125 <= res && res < 0)
      {
        errno = -res;
        res   = -1;
      }

      return res;

}

and here is int main () : 这是int main ()

 int main() {
     int fd = 432423;
     char buf[128];
     size_t count = 128;
     my_read(fd, buf, count);

     return 0;
 }

Am I doing something wrong ? 难道我做错了什么 ? maybe it's because of the volatile ? 也许是因为volatile

I've tried to debug the code , and when Eclipse goes into my_read(fd, buf, count); 我尝试调试代码,当Eclipse进入my_read(fd, buf, count); and gets to the line __asm__ volatile( in my_read , it fails and goes into if (-125 <= res && res < 0) ... 并进入__asm__ volatile(my_read ,它失败并进入if (-125 <= res && res < 0) ...

EDIT : 编辑:

ssize_t my_read(int fd, void *buf, size_t count)

{

      ssize_t res;

      __asm__ volatile(
        "int $0x80"        /* make the request to the OS */
        : "=a" (res)       /* return result in eax ("a") */

        : "a"  (5) ,      /* passing the system call for read to %eax , with call number 5  */
          "b" (fd),     /* pass arg1 in ebx ("b") */
          "c" (buf),     /* pass arg2 in ecx ("c") */
          "d" (count)      /* pass arg3 in edx ("d") */

        : "memory", "cc"); /* announce to the compiler that the memory and condition codes have been modified */

      /* The operating system will return a negative value on error;
       * wrappers return -1 on error and set the errno global variable */

      if (-125 <= res && res < 0)
      {
        errno = -res;
        res   = -1;
      }

      return res;

}

and main : 和主要:

 int main() {
     int fd = 0;
     char buf[128];
     size_t count = 128;
     my_read(fd, buf, count);

     return 0;
 }

it fails and goes into if (-125 <= res && res < 0) 它失败并且进入if (-125 <= res && res < 0)

Where did you expect it to go? 您期望它去哪里?

I expect the read system call to fail with -EINVAL , as you are not pasing in a valid file descriptor to it. 我希望读取系统调用因-EINVAL失败,因为您没有在其中粘贴有效的文件描述符。

Update: 更新:

Where did you get an idea that SYS_read is 5 ? 您从哪里知道SYS_read5

On my system, SYS_read is 3 in 32-bit mode, and 0 in 64-bit mode: 在我的系统上, SYS_read在32位模式下为3 ,在64位模式下为0

echo "#include <syscall.h>" | gcc -xc - -dD -E | grep ' __NR_read '
#define __NR_read 0

echo "#include <syscall.h>" | gcc -xc - -dD -E -m32 | grep ' __NR_read '
#define __NR_read 3

Assuming you are on 32-bit system, you are invoking SYS_open , which is failing with -EFAULT (-14) because the first parameter to the open system call is supposed to be a filename and 0 ( NULL ) isn't a valid filename. 假设您使用的是32位系统,那么您正在调用SYS_open ,它以-EFAULT (-14)失败,因为打开系统调用的第一个参数应该是文件名,而0NULL )是无效的文件名。

strace下运行它以确保确定发生了什么,但是我认为您的问题是您将所有输入放在输出寄存器列表中,而不是在输入寄存器列表中...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM