Thread: an help with IA32 assembly?

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    100

    an help with IA32 assembly?

    hello everybody! I don't know if I am allowed to post this topic here.. If not, I apologize for this in advance..
    I just began learning IA32 assembly and wanted to write a simple program which is supposed to compare 2 numbers stored in reg EAX and EBX byte by byte and store the biggest in ECX. My code doesn't work when the most significant byte starts with 1. For example in the code below it doesn't work properly.. Could anybody help me to find out the mistake please?

    Thanks a lot!

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    unsigned max;
    void printbit (unsigned n);
    
    int main()
    {
    	asm(
    	"pushl %eax\r\n"
    	"pushl %ebx\r\n"
    	"pushl %ecx\r\n" //RESULT
    	"pushl %edx\r\n" //COUNTER
    	"pushl %esi\r\n" //BIT MASK
    	"pushl %ebp\r\n" //STORE RESULT OF EAX AND BITMASK
    	"pushl %edi\r\n" //STORE RESULT OF EBX AND BITMASK
    	
    	"movl $0b11111111000001010001000000000000, %eax\r\n"//INIZIALIZE EAX
    	"movl $0b00000000011000000000000011111111, %ebx\r\n"//INIZIALIZE EBX
    	
    	"movl $0b00000000000000000000000011111111,%esi\r\n"//INIZIALIZE MASK
    	"xorl %ecx,%ecx\r\n"//RESET TOTAL
    	"xorl %edx,%edx\r\n"//RESET COUNTER
    	
    	"cicle:\r\n"
    	"movl %eax,%ebp\r\n"
    	"movl %ebx,%edi\r\n"
    	"andl %esi,%ebp\r\n"
    	"andl %esi,%edi\r\n"
    	"cmp %ebp,%edi\r\n"
    	"jg use_edi\r\n"
    	"xorl %ebp,%ecx\r\n"
    	"ret:\r\n"
    	"cmp $3,%edx\r\n"
    	"je end\r\n"
    	"incl %edx\r\n"
    	"shl $8,%esi\r\n"
    	"jmp cicle\r\n"
    	
    	"use_edi:\r\n"
    	"xorl %edi,%ecx\r\n"
    	"jmp ret\r\n"
    	
    	"end:\r\n"
    	"movl %ecx,max\r\n"
    	"popl %edi\r\n"
    	"popl %ebp\r\n"
    	"popl %esi\r\n"
    	"popl %edx\r\n"
    	"popl %ecx\r\n"
    	"popl %ebx\r\n"
    	"popl %eax\r\n"
    	);
    	
    	printbit(max);
    }
    
    void printbit (unsigned n)
    {
    	unsigned bits=sizeof (unsigned)*8;
    	unsigned mask = 1<<(bits-1);
    	int i;
    	for (i=0;i<bits;i++)
    	{
    		if (mask&n)putchar('1');
    		else putchar('0');
    		mask>>=1;
    	}
    	printf("\n");
    }

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by smoking81 View Post
    hello everybody! I don't know if I am allowed to post this topic here.. If not, I apologize for this in advance..
    I just began learning IA32 assembly and wanted to write a simple program which is supposed to compare 2 numbers stored in reg EAX and EBX byte by byte and store the biggest in ECX.
    You are using a signed conditional branch. Instead of using "JG" use "JA"

    Code:
    "ja use_edi\r\n"
    Last edited by brewbuck; 03-20-2008 at 08:37 PM.

  3. #3
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by brewbuck View Post
    You are using a signed conditional branch. Instead of using "JG" use "JA"

    Code:
    "ja use_edi\r\n"
    ops... Thanks a lot! bye

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    hello!
    I'd have another question...
    in another simple program i should rotate a number according to the value contained in a registry... Since it's not possible to do things like

    Code:
    ror &#37;eax,%ebx
    (supposing that eax contains the number which says of how many positions rotating)..

    isn't there another way to do this which is different than making a loop of
    Code:
    ror $1,%ebx
    ?

    thanks x your help! bye

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    you can do "ror %cl, %ebx" - the count MUST be in %ecx.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by matsp View Post
    you can do "ror %cl, %ebx" - the count MUST be in %ecx.

    --
    Mats
    the text of the exercise claims that ECX must contain the counter K of the positions to rotate.. This should be meant to force me to use a loop?

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    if ECX already contains the amount to rotate, then "ror %cl, %ebx" will be exactly what you want [assuming you have the right data in %ebx].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by matsp View Post
    if ECX already contains the amount to rotate, then "ror %cl, %ebx" will be exactly what you want [assuming you have the right data in %ebx].

    --
    Mats
    i'm sorry i did a small mess... I wanted to say that ECX contains the value which should be rotated... Let's say that i'd like to do this:

    Code:
    ror %edx,%ecx
    edx is the counter

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    No, the counter HAS to be in %cl (which is the low 8 bits of ecx. Swap your registers around).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Why do you use \r\n? This is Linux, \n is enough. But you might want to use \n\t to make the resulting assembly readable.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by matsp View Post
    No, the counter HAS to be in %cl (which is the low 8 bits of ecx. Swap your registers around).

    --
    Mats
    then either i turn around the problem by swapping registers as you suggest, either i have to do something like this (which of course works, but it's not the fastest way):

    Code:
    ...
    "rotateR:\r\n"
    "xorl %edi,%edi\r\n"
    "cicle:\r\n"
    "cmp %edi,%edx\r\n"
    "je end\r\n"
    "ror $1,%ecx\r\n"
    "incl %edi\r\n"
    "jmp cicle\r\n"
    ...
    isn't it?

  12. #12
    Registered User
    Join Date
    Oct 2007
    Posts
    100
    Quote Originally Posted by CornedBee View Post
    Why do you use \r\n? This is Linux, \n is enough. But you might want to use \n\t to make the resulting assembly readable.
    ops.. it's true i don't know i saw an example written by a friend of mine and i continued doing this mistake!

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by smoking81 View Post
    then either i turn around the problem by swapping registers as you suggest, either i have to do something like this (which of course works, but it's not the fastest way):

    Code:
    ...
    "rotateR:\r\n"
    "xorl %edi,%edi\r\n"
    "cicle:\r\n"
    "cmp %edi,%edx\r\n"
    "je end\r\n"
    "ror $1,%ecx\r\n"
    "incl %edi\r\n"
    "jmp cicle\r\n"
    ...
    isn't it?
    Yes, if you swap ecx with edx [you can always swap them back afterwards, but that's reducing the efficency of the multi-step rotate].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    When programming x86, it helps to be aware of the special functions of certain registers. Had you known of this special property of ECX (the fact that it can be used as the count argument of a rotate or shift instruction), you might have avoided using it for some other purpose in the first place.

    There is actual method to this madness.

    The "A" in EAX means "accumulator," because that's what it is.
    The "B" in EBX means "base."
    The "C" in ECX means "count."
    The "D" in EDX means "data."
    The "SI" in ESI means "source index."
    The "DI" in EDI means "destination index."
    The "BP" in EBP means "base pointer."

    This is not a coincidence! The register pair EAX:EDX serves as data for the long multiplication and division instructions. BX, historically, used to be the only general register which could be used to index memory (although SI and DI could also be used), or to do indirect calls/jumps, although that restriction has now been relaxed. CX holds the counters for various kinds of operations, including multi-bit rotation. SI and DI are implicit operands of the string instructions. And BP has the special property that it accesses the stack segment, not the data segment, when dereferenced.

    You have to constantly keep these things in mind as you choose which registers to use for which variables, because if you plan poorly, you'll continually be swapping/pushing/saving/restoring them.

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The differences were greater in early x86 chips than they are now. For example, an addition using ax/eax as the target register was considerably faster than one using a different register.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. IA32 Assembly
    By Smohr in forum C Programming
    Replies: 13
    Last Post: 05-07-2009, 08:01 PM
  2. C to assembly interface
    By Roaring_Tiger in forum C Programming
    Replies: 4
    Last Post: 02-04-2005, 03:51 PM
  3. assembly language...the best tool for game programming?
    By silk.odyssey in forum Game Programming
    Replies: 50
    Last Post: 06-22-2004, 01:11 PM
  4. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  5. C,C++,Perl,Java
    By brusli in forum C Programming
    Replies: 9
    Last Post: 12-31-2001, 03:35 AM