View Full Version : an help with IA32 assembly?
smoking81
03-20-2008, 04:34 PM
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!
#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");
}
brewbuck
03-20-2008, 08:35 PM
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"
"ja use_edi\r\n"
smoking81
03-21-2008, 05:49 AM
You are using a signed conditional branch. Instead of using "JG" use "JA"
"ja use_edi\r\n"
ops... :) Thanks a lot! bye
smoking81
03-28-2008, 08:32 AM
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
ror %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
ror $1,%ebx
?
thanks x your help! :) bye
matsp
03-28-2008, 08:36 AM
you can do "ror %cl, %ebx" - the count MUST be in %ecx.
--
Mats
smoking81
03-28-2008, 08:42 AM
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?
matsp
03-28-2008, 08:45 AM
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
smoking81
03-28-2008, 08:52 AM
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:
ror %edx,%ecx
edx is the counter
matsp
03-28-2008, 09:00 AM
No, the counter HAS to be in %cl (which is the low 8 bits of ecx. Swap your registers around).
--
Mats
CornedBee
03-28-2008, 09:04 AM
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.
smoking81
03-28-2008, 09:15 AM
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):
...
"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?
smoking81
03-28-2008, 09:19 AM
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! :)
matsp
03-28-2008, 10:16 AM
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):
...
"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
brewbuck
03-28-2008, 11:11 AM
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.
CornedBee
03-28-2008, 11:14 AM
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.
smoking81
03-29-2008, 01:38 AM
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.
wow this is what "mnemonic" means.. :)
thanks!
vBulletin® v3.7.0, Copyright ©2000-2009, Jelsoft Enterprises Ltd.