1

asm volatile を使用して read() システム コールのラッパー関数を作成しようとしていますが、res がその値を変更しないため、機能しません。

コードは次のとおりです。

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;

}

そしてここにありますint main ()

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

     return 0;
 }

私は何か間違っていますか?たぶんそれのせいvolatileですか?

コードをデバッグしようとしましたが、Eclipse が に入りmy_read(fd, buf, count); 、 の行 __asm__ volatile(に到達するmy_readと、失敗してif (-125 <= res && res < 0)...に入ります。

編集 :

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;

}

そしてメイン:

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

     return 0;
 }
4

2 に答える 2

5

それは失敗して入りますif (-125 <= res && res < 0)

どこに行くと思っていましたか?

-EINVAL有効なファイル記述子を渡していないため、 read システムコールが で失敗することが予想されます。

アップデート:

SYS_readというアイデアはどこから得たの5ですか?

私のシステムでSYS_read3、32 ビット モードと064 ビット モードです。

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

32 ビット システムを使用していると仮定すると、open システム コールの最初のパラメータはファイル名であり、( ) は有効なファイル名ではないため、(-14)SYS_openで失敗します。-EFAULT0NULL

于 2012-04-21T15:17:20.437 に答える
2

実際に実行してstrace何が起こっているかを確認してください。しかし、問題は、すべての入力を入力レジスタ リストではなく出力レジスタ リストに入れることだと思います...

于 2012-04-21T15:16:20.907 に答える