Re: Struggling with conversion to AMD64/Linux syscalls in inline asm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi me,

me wrote:
I'm trying to convert some 32 bit linked asm (which runs fine) into 64 bit inline asm (g++) but am stumbling at the first hurdle
ie I'm getting -14 returned as the file descriptor for /dev/vcsa1.

Do you have the rights to access this file?
On the host here, it's not available to ordinary users.
(but see below, there is another problem)
(try a normal C++ program and check if the access is allowed)

Here's my attempt.

[code]
//My amd64 inline asm version #include <iostream>
using namespace std;

void my_fn(){
   const char * fl =       "/dev/vcsa1";
   const char * test_str = "          "; //make same size as fl
int test_int = -1; //ie initialised to fail unless replaced by value //1 open /dev/vcsa1 & return file descriptor in rax __asm__ __volatile__(
   ".equ sys_open, 2\n"
".equ O_RDWR, 02\n" "mov $sys_open, %%rax\n" "mov $O_RDWR, %%rcx\n" "mov $0600, %%rdx\n" //read/write for user in x86. Not sure for AMD64? "syscall\n" :"=b"(test_str), "=a"(test_int)
   :"b"(fl)

wrong registers.
Try that instead:
   __asm__ __volatile__(
   ".equ sys_open, 2\n"
   ".equ O_RDWR, 02\n"
   "mov $sys_open, %%rax\n"
   "mov $O_RDWR, %%rsi\n"
   "mov $0600, %%rdx\n" //read/write for user in x86. Not sure for AMD64?
   "syscall\n"
   :"=a"(test_int)
   :"D"(fl)
   );

Check the documentation of linux syscall on AMD64
(sorry, no links, must not be too hard to get though...).
I just compiled a normal open to see what was
done by libc, leading to the change.
I'm not very familiar with amd64 and linux syscalls.

Note that your test_str does not make much sense.
What your asm statement does is replace the address
it points to to fl. And by the way you are double lucky
it works since the string  full of ' ' you allocate would
exist in read-only memory and normally you should
have a crash, but since you don't touch it at all,
you are well, triply lucky. (If I understand what
you /expected/, not what you actually /wrote/.)

); //test file name in rbx and returned file descriptor
   cout << test_str << endl; // /dev/vcsa1                     pass
cout << test_int << endl; // 2 before syscall -14 after ie fail }

int main(){
   my_fn();
   return 0;
}
[/code]

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux