Hi,
How is it possible to packing two characters into an unsigned integer? Can i pack anything else ?
And after i pack the two characters into the unsigned int, how do i unpack them ?
thnx
Hi,
How is it possible to packing two characters into an unsigned integer? Can i pack anything else ?
And after i pack the two characters into the unsigned int, how do i unpack them ?
thnx
Last edited by Nutshell; 01-27-2002 at 08:23 AM.
I wrote the code, it worked, is it alright? DId i do a good job?
Code:#include <stdio.h> void packCharacters( char c1, char c2 ); void displayBits( unsigned value ); void unpack( unsigned value ); int main() { unsigned num; char char1, char2; printf( "Enter 2 characters: " ); scanf( "%c %c", &char1, &char2 ); printf( "Character 1 in binary: \n" ); displayBits( char1 ); printf( "Character 2 in binary: \n" ); displayBits( char2 ); printf( "Packed characters in binary: \n" ); packCharacters( char1, char2 ); printf( "\n" ); system( "PAUSE" ); return 0; } void displayBits( unsigned value ) { unsigned c, displayMask = 1 << 31; printf( "%7u = ", value ); for ( c = 1; c <= 32; c++ ) { putchar( value & displayMask ? '1' : '0' ); value <<= 1; if ( c % 8 == 0 ) putchar( ' ' ); } putchar( '\n' ); } void packCharacters( char c1, char c2 ) { unsigned packed; packed = c1; packed <<= 8; packed |= c2; printf( "CHARACTER - %c\n", packed ); displayBits( packed ); printf( "\n" ); unpack( packed ); } void unpack( unsigned value ) { char c1, c2; c1 = value; printf( "Character 2 unpacked: %c\n", c1 ); value >>= 8; c2 = value; printf( "CHaracter 1 unpacked: %c\n\n", c2 ); }
And if my logic is right, i can actually pack 4 characters into an unsigned integer?
#define PACK16LOHI(v1,v2) (unsigned int)(((v2)<<8)+v1)
just do opposite to unpack
you did a fine job Nutshell :)
I actually use a single short ( ie 16 bit ) integer to store six pieces of information in my program. To extract them I shift left then right rather than use a mask ( whether it is quicker I don't know because although speed is important it is not absolutely critical at that point and certainly it makes my brain hurt less )
Asm is about twice as quick as >> and << plus I have been using asm for years and it is always easier to use familiar methods ...Code:int dummy, myinteger; myinteger=dummy; _asm{ //Find SECOND variable on "RHS" Bits 4 to 6 mov ax,dummy shl ax,3 ;Shift 3 "bits" to extreme left shr ax,13 ;Shift 13 "bits" to extreme right mov dummy,ax } //dummy now has value represented by bits 4 to 6 //eg dummy = 7 ( 0000 0000 0000 0111 )
Another benefit of packing six pieces into one integer is that I require random values and by just getting one random integer I get six random values ( you still there?)
Nutshell
You can use asm in C very simply. To take an example from the program I am working on.
C Instruction:
liner++;
We all know this increases the value of liner by one. When I look at the disassembly ( the C compiler turns everything into machine code and the disassembler shows the asm equivalent ) of this I see:
_asm{
mov dx,word ptr [ebp-24h]
add dx,1
mov word ptr [ebp-24h],dx
}
This shows that the code loads the contents of liner held at address ebp-24h into the dx register. Then it adds one then it loads it back. There are three instructions. There may be good reasons for this but if so I am not sure what they are ... the same can be achieved by:
_asm{inc liner}
or _asm{mov liner,1}
So, by using this I have speeded up my program ( I've timed it ) Incidentally, the C compiler translates
_asm{inc liner }
into:
_asm{inc word ptr [ebp-24h]}
Many instructions can be doubled in speed by using simple asm.
Thing is, i don't know any assembly. Is there a website or e-book that can help me with the basics of using asm in C or C++ ?
thnx
I own over 30 books on C bought over many years - intending one day to read them! In total I guess they contain about twenty ( at the most ) pages on inline C. I guess it is not a very fashionable subject.
Learning pure asm is not trivial and it is difficult to buy books on it as most major bookshops no longer sell them. If you try to teach yourself you can do some amazing things to your machine ( actually in learning C I managed to do the most amazing thing by badly misusing a function - for some baffling reason it renamed all my hard drive partitions so instead of hard drives C, D, E and a replaceable zip drive F it made D the zip drive. What a mess! )
You will see that I have just put a thread up on the subject of inline asm so maybe others will make observations. I appreciate that I am not being very helpful by saying "inline asm is brill" and then saying "not sure how you would learn to use it" but that is how I see it.
You can try:
http://www.google.com/search?q=learn%20inline%20asm
or if you want a choice of search engines you could try:
http://www.searchthingy.com/search.asp?ab
which is pretty good ( or ought to be - its my site )
Go to www.webster.csr.edu and download AoA to learn assembly
I did not use assembly to pack cuz most yell at me if I use it here. You can also do pure asm functions and call them like C functions. Also for large numbers, MMX packs very fast. Only works on x86 though. And yes, shl and shr are faster than << >>.
My #define will pack 2 char into an integer and will not cause any stack overhead because it is a #define.
Whether you do it in assembly or not is up to you and depends on how fast you need it to be. If you are packing data into a video buffer then it needs to be fast, but if you are packing data to save to disk or something I would not call that a speed critical task. Besides, the << >> translate to shr and shl when you compiler compiles the code, or at least they should. So, either way should be fast enough for what you need to do.
Here is how VC++6 disassembles:
It uses 10 lines of asm for what is a 2 or 3 line job!Code:403: code[liner][1] >>= 13; //Shift 13 "bits" to extreme right .. 004027C7 mov edx,dword ptr [ebp-0Ch] 004027CA and edx,0FFFFh 004027D0 shl edx,4 004027D3 mov ax,word ptr code+2 (00434fda)[edx] 004027DA shr ax,0Dh 004027DE mov ecx,dword ptr [ebp-0Ch] 004027E1 and ecx,0FFFFh 004027E7 shl ecx,4 004027EA mov word ptr code+2 (00434fda)[ecx],ax
As for speed, my current prog does up to 500 billion trips through the central loop when it runs overnight so even one extra line is critical.
Incidentally, calls are pretty wasteful if time is vital - each call seems to add about 20 lines of pushing, popping and xoring!
But i really have absolutely no knowledge of assembly except for what it is. WHat is inline ?
"What is inline asm?"
Ah! Right. I sort of assumed it was obvious but very little is obvious until you know it.
Inline asm is a facility in the C language where you can incorporate Assembly Language instructions into C programs. An example
This very simple example multiplies dummy by 4 and is directly equivalent to dummy=dummy*4; But MUCH quicker.Code:main(){ unsigned short dummy=10; _asm{ ;This is a comment - we use; not //! shl dummy,2 ;Shift all bits 2 to the left } }
You can use inline asm to greatly speed up programs and also work directly with the individual bits that constitute numbers. All data consist of strings of separate bits ( usually 4, 8, 16, 32 or 80 ) and you can do practically anything with them as in the example above. At the fundamental level there is no such thing as an integer or a string - they are just bits - zero or one. Millions of 'em.
}