Я пытаюсь написать функцию-оболочку для системного вызова read (), используя asm volatile, но это не сработает, поскольку 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; }
он терпит неудачу и переходит в
if (-125 <= res && res < 0)
Где вы ожидали, что он пойдет?
Я ожидаю, что системный вызов read завершится с -EINVAL
, так как вы не используете его в действительном дескрипторе файла.
Обновить:
Откуда у вас возникла идея, что SYS_read
- 5
?
В моей системе SYS_read
имеет 3
в 32-битном режиме и 0
в 64-битном режиме:
echo "#include " | gcc -xc - -dD -E | grep ' __NR_read ' #define __NR_read 0 echo "#include " | gcc -xc - -dD -E -m32 | grep ' __NR_read ' #define __NR_read 3
Предполагая, что вы находитесь на 32-битной системе, вы вызываете SYS_open
, который не работает с -EFAULT
(-14), потому что первый параметр открытого системного вызова должен быть именем файла, а 0
( NULL
) не является допустимым именем файла ,
Запустите его в strace
чтобы узнать, что происходит наверняка, но я думаю, ваша проблема в том, что вы помещаете все входы в список выходных регистров, а не в список входных регистров …