OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 9:52 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Inline assembly : reading a register [SOLVED]
PostPosted: Wed Oct 21, 2015 10:01 am 
Offline

Joined: Thu Nov 20, 2014 4:06 pm
Posts: 23
I'm trying to do a 64-bit kernel in C on gcc so I need to read from a register in inline assembly.

Here's my attempt :

main.c :

Code:
asm(".intel_syntax noprefix");  //Use of NASM

int main(void){

    clear();

    asm("mov rax, 0x1");    //I try to change the default value of Rax
                            //  which is 0 on Qemu

    long rax;
    rax = readRax();

    char * str;
    str = itoa(rax);   
    print(str);

    while(1){};
    return 1;

}

my readRax function :

Code:
long readRax(){

    long rax;
    asm("mov %%rax, %0"
    :"=r"(rax)
    );
    return rax;
}


The problem is that on my qemu screen "0" is still displayed and not "1".


Last edited by remy on Wed Oct 21, 2015 10:50 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Inline assembly : reading a register
PostPosted: Wed Oct 21, 2015 10:33 am 
Offline
Member
Member
User avatar

Joined: Thu Mar 27, 2014 3:57 am
Posts: 568
Location: Moscow, Russia
You can't rely on that code, the compiler can insert any assembly code anywhere, you can't determine the state of RAX.

_________________
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay


Top
 Profile  
 
 Post subject: Re: Inline assembly : reading a register
PostPosted: Wed Oct 21, 2015 10:49 am 
Offline

Joined: Thu Nov 20, 2014 4:06 pm
Posts: 23
Do you have a dummy example of how to insert the code setting RAX to 1 in my readRax() asm bloc ?
Thanks,


Top
 Profile  
 
 Post subject: Re: Inline assembly : reading a register
PostPosted: Wed Oct 21, 2015 12:31 pm 
Offline
Member
Member
User avatar

Joined: Fri Jan 16, 2009 8:34 pm
Posts: 284
Location: Louisiana, USA
Though you cannot rely on inline asm (especially for *ax, *cx, and *dx ["caller save" registers]), the only possible issue I see with the actual code is:
Code:
asm(".intel_syntax noprefix");  //Use of NASM
...
asm("mov rax, 0x1");    //I try to change the default value of Rax
...
asm("mov %%rax, %0"
    :"=r"(rax)
    );
...
Why are you mixing Intel and AT&T syntax? Does the asm routine in readRax know it is AT&T syntax?

Also use volatile prefix on inline asm to keep compiler from optimizing out the ASM. (it may think rax should be 0, so the second asm instruction may be changed to "rax = 0;" by the compiler)

_________________
BOS Source Thanks to GitHub
BOS Expanded Commentary
Both under active development!
Sortie wrote:
  • Don't play the role of an operating systems developer, be one.
  • Be truly afraid of undefined [behavior].
  • Your operating system should be itself, not fight what it is.


Top
 Profile  
 
 Post subject: Re: Inline assembly : reading a register
PostPosted: Wed Oct 21, 2015 12:46 pm 
Offline
Member
Member

Joined: Sun Feb 01, 2009 6:11 am
Posts: 1070
Location: Germany
You probably do read the value of rax. It's jus that the question doesn't make any sense because you can't know what the value in rax means at that point. The compiler is using the register to run your C code, so it has long been changed since you originally set it. You can only assume that the register stays the same within the same asm() block. You also need to specify each register that you change either in the output list or in the clobber list so that the compiler knows that you're going to overwrite its data.

_________________
Developer of tyndur - community OS of Lowlevel (German)


Top
 Profile  
 
 Post subject: Re: Inline assembly : reading a register
PostPosted: Wed Oct 21, 2015 2:43 pm 
Offline
Member
Member
User avatar

Joined: Wed Aug 05, 2015 5:33 pm
Posts: 159
Location: Drenthe, Netherlands
My best bet would be that it's somewhere on the stack. The calling convention afaik is that ax is saved and restored by whatever code that is calling your function.

Edit: Oh I overlooked that your changing the value in the function itself with inline assembly. It seems C has it's own plans with that register. You might want to disassemble that code to see whats really happening. 'objdump -d file.o > file.list'

_________________
"Always code as if the guy who ends up maintaining it will be a violent psychopath who knows where you live." - John F. Woods

Failed project: GoOS - https://github.com/nutterts/GoOS


Top
 Profile  
 
 Post subject: Re: Inline assembly : reading a register
PostPosted: Wed Oct 21, 2015 10:47 pm 
Offline

Joined: Thu Nov 20, 2014 4:06 pm
Posts: 23
The problem is that I was compiling with gcc's -masm=intel option.
Furthermore it is effectively not a good idea to use a system register, except if you change it in the same asm block.
Here is a solution :



Code:
long readRax(){
   
   long rax;
   
   asm( "mov $1, %%rax\n" \    //Set Rax to 1
        "mov %%rax, %0\n"  \
              :"=r"(rax)
              );
}

int main(void)
{
   
   clear();
   
   long rax;
   rax = readRax();

   while(1){};
   return 1;
}



Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 85 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group