me wrote:
I now get a file descriptor of 3 when opening /dev/vcsa1 thanks to Bob
Platz, Jie Zhang, Thomas Martiz & Cedrix Roux. Bob and Cedric showed me
that the registers used in 64bit linux are different. Both codes now
give 3 which seems reasonable.
Unfortunately I'm now stuck on the read bit. Here's where I've got to
so far...
//My amd64 inline asm version
//this now returns a file descriptor of 3
#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; //fails unless replaced by value
unsigned char buf[] = {0,0,0,0};
//1 open /dev/vcsa1 & return file descriptor in rax
__asm__ __volatile__(
".equ sys_open,2\n"
".equ O_RDWR,02\n"
"movq $sys_open,%%rax\n"
"movq $O_RDWR,%%rsi\n"
"movq $0600,%%rdx\n" //read/write for user in x86. Not sure for AMD64?
"syscall\n"
:"=D"(test_str),"=a"(test_int)
:"D"(fl) //rdi
:"rsi","rdx","rcx","r10","r11","cc" //Is this enough
);
//cout << test_str << endl; // /dev/vcsa1 ie pass
//cout << test_int << endl; // 3 ie pass
//read 1st 4 bytes of file into buf[]
__asm__ __volatile__(
"movq %%rax, %%rsi\n" //returned file descriptor into rsi
"movq $0,%%rax\n" //syscall read into rax
"movq $4,%%rdx\n" //qty of bytes to read into rdx
"syscall\n"
:"=a"(test_int)
:"D"(&buf[0]) //ptr of where to place 1st byte into rdi
:"rsi","rdx","rcx","r10","r11","cc"
);
cout << test_int << endl; //returning -9 expected 4 ie fail
}
int main(){
my_fn();
return 0;
}
Yes the syscall numbers in 64 bit linux is different to x86 and I do
take the point that I'm lucky with my output variables.
I expect read to return 4 instead of -9.
Read that:
http://www.x86-64.org/documentation/abi.pdf
especially appendix A.
You see that order of registers is %rdi, %rsi, %rdx, %rcx, ...
read is ssize_t read(int fd, void *buf, size_t count);
so put fd in %rdi, buf in %rsi, and count in %rdx
So in your code replace "rsi" by "rdi" and 'D' by 'S'
(and don't forget to change rsi in the clobber list too,
but is it necessary to put all what you put in there?
I don't know; this list is to tell gcc what registers
the asm statement changes, I doubt syscall changes
anything; anyway, some more experienced people may
give you nice pointers with good explanations).
Regards,
Cédric.