问题
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 .
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 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 ?
I've tried to debug the code , and when Eclipse goes into 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) ...
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;
}
回答1:
it fails and goes into
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.
Update:
Where did you get an idea that SYS_read is 5?
On my system, SYS_read is 3 in 32-bit mode, and 0 in 64-bit mode:
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.
回答2:
Run it under strace to see what's happening for sure, but I think your problem is that you put all the inputs in the output register list rather than the input register list...
来源:https://stackoverflow.com/questions/10260178/inline-assembler-for-wrapper-function-doesnt-work-for-some-reason