Thread: Assembly Language Help ;)

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    199

    Wink Assembly Language Help ;)

    Hi,

    I'm running some simple assembler code to try and get the details of the CPU. I'm compiling using Code::Blocks so here is the code

    Code:
    #include <iostream>
    
    int main()
    {
        int i = 0;
    
        char* ptr1 = new char[4];
    
        std::cout << ptr1 << std::endl;
    
        asm("movl %1, %%eax; CPUID; movl %%ebx, %0;"
            :"=r"(ptr1)  // output %0
            :"r"(i)  // input %1
            :"%eax","%ebx");
    
        std::cout << ptr1[0] << std::endl;
    
        return 1;
    }
    Ok but I'm having some problems. As far as I understand it, the CPUID instruction causes data to be written into the registers ebx,ecx and edx. Ok great 4 bytes a piece. So I made a char array which can hold 4 chars, 1 byte each. I move the int 0 into eax and then commence the instruction and then move the first 4 bytes coming from ebx to the pointer variable.

    I'm doing something wrong here though. I get the feeling this is too simplified, but I really don't know how to progress. Can anyone offer any insight here? Many thanks

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You don't need to use new here.
    Furthermore, your code is leaking memory, again a reason not to use new.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Bad assembly! The standard says that 'ebx' must remain the same.
    Code:
    "push %%ebx;"
    .....
    "pop  %%ebx;"
    EDIT: Not to mention that you pass ptr1 as register. Do you expect that GCC's gonna guess you're passing a pointer? Think again! 'ebx' is passed to 'ptr1', not '*ptr1' !
    Last edited by GReaper; 03-05-2011 at 08:50 AM.
    Devoted my life to programming...

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    What standard?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Quote Originally Posted by Elysia View Post
    What standard?
    Sorry, wrong word. There's no actual standard, but i've read it here.
    Devoted my life to programming...

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah, I see. You just need to remember that calling conventions as they're called is not standard. They vary from compiler to compiler (and platform to platform).
    So basically you have to be aware of the calling convention used by your platform/compiler to write good assembly.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    Thanks for the replies. I'll go and fix the memory leak, this code is, as I already know really, total cr@p at the moment

    I wasn't even aware of any special instructions concerning pointers, I think I need to investigate push and pop

    I thought that given that the register can hold a 32 bit value - 4 bytes and a char is 8 bits - 1 byte I might be ok trying to copy the contents of the register to a variable which is initialised to point to a place with 4 bytes of memory allocated.

    Maybe that is indeed a correct assumption but I'm obviously not using proper syntax here. Exactly what would I need to do to get those 4 bytes from ebx into the address pointed to by the variable ptr1?

    Thanks

  8. #8
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Quote Originally Posted by shrink_tubing View Post
    Exactly what would I need to do to get those 4 bytes from ebx into the address pointed to by the variable ptr1?
    "=p" instead of "=r" ( The easy work-around )
    Devoted my life to programming...

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    199

    Smile

    Thanks for everyone's help! I finally got it to work after alot of reading. Here is a very inefficient but working version:

    Code:
    #include <iostream>
    #include <stdio.h>
    
    int main()
    {
        char* ptr1 = new char[4];
        char* ptr2 = new char[4];
        char* ptr3 = new char[4];
    
        asm("movl %0, %%esi; movl $0, %%eax; CPUID; movl %%ebx, (%%esi);"
            :
            :"m"(ptr1)
            :"memory","%eax","%ebx","%esi");
    
        asm("movl %0, %%esi; movl $0, %%eax; CPUID; movl %%edx, (%%esi);"
            :
            :"m"(ptr2)
            :"memory","%eax","%edx","%esi");
    
        asm("movl %0, %%esi; movl $0, %%eax; CPUID; movl %%ecx, (%%esi);"
            :
            :"m"(ptr3)
            :"memory","%eax","%ecx","%esi");
    
        for(int i = 0; i < 4; i++)
        {
            printf("%c",ptr1[i]);
        }
    
        for(int i = 0; i < 4; i++)
        {
            printf("%c",ptr2[i]);
        }
    
        for(int i = 0; i < 4; i++)
        {
            printf("%c",ptr3[i]);
        }
    
        delete ptr1;
        delete ptr2;
        delete ptr3;
    
        return 1;
    }
    This will print the 12 character name of the processor to the screen using AT&T syntax as used in the Code:Blocks compiler which I believe is of type GCC

  10. #10
    Registered User
    Join Date
    Jan 2010
    Posts
    199

    Thumbs up Finally!

    Here's a much neater, nicer version:

    Code:
    #include <stdio.h>
    
    int main()
    {
        char* ptr = new char[12];
    
        asm("movl %0, %%esi;"
            "movl $0, %%eax;"
            "CPUID;"
            "movl %%ebx, (%%esi);"
            "movl %%edx, 4(%%esi);"
            "movl %%ecx, 8(%%esi);"
            :
            :"m"(ptr)
            :"memory","%eax","%esi");
    
        for(int i = 0; i < 12; i++)
        {
            printf("%c",ptr[i]);
        }
    
        delete ptr;
    
        return 1;
    }
    I'm not sure if I should have registers ebx,ecx and edx on the clobber list though. DO I need to do that or will the instruction CPUID automatically inform the machine that the registers ebx,ecx and edx have been written to and it can no longer depend on those values being as they were before the CPUID instruction was run?

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    doesn't gcc preserve registers for you if you list them in the clobber list?

  12. #12
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Quote Originally Posted by Elkvis View Post
    doesn't gcc preserve registers for you if you list them in the clobber list?
    Yes, i forgot.
    Devoted my life to programming...

  13. #13
    Registered User
    Join Date
    Jan 2010
    Posts
    199
    Well although it may be inefficient I am going to add all affected registers to the clobber list, just to make sure. This code only executes once during boot up so it's ok from that persepctive. I would imagine it isn't guaranteed that CPUID will inform GCC that registers ebx,ecx and edx are affected which may screw something up in the future if it expects to find a certain variable in a register such as say ebx only to find a 4 byte string ;o)

    Thanks for the help anyway

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The code is still even worse now. You turned code with memory leaks into code with undefined behavior.
    Why are you using new in the first place? Get rid of it!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jan 2010
    Posts
    199

    Thumbs up

    Quote Originally Posted by Elysia View Post
    The code is still even worse now. You turned code with memory leaks into code with undefined behavior.
    Why are you using new in the first place? Get rid of it!
    Your 17000+ posts suggests to me you know a thing or two about programing. I'd be interested to know why the code has undefined behaviour as I honestly can't see it - which means I'm missing something. I know you're right, I just don't know why. What would I need to do to correct this?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assembly language.
    By JOZZY& Wakko in forum Tech Board
    Replies: 0
    Last Post: 12-18-2009, 05:58 AM
  2. Why C Matters
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 136
    Last Post: 01-16-2008, 09:09 AM
  3. Assembly Language Forums??
    By gqchynaboy in forum Tech Board
    Replies: 3
    Last Post: 11-22-2004, 06:59 AM
  4. Language Script..
    By vasanth in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 03-30-2003, 06:48 AM
  5. help in assembly language
    By ema in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 12-14-2002, 02:22 AM