Click here to Skip to main content
15,886,046 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello again,

Once more, I have a question:
When I have ->
MOV AL,BYTE PTR DS:[ESI+ECX]
or
MOV AH,...
or
MOV AX,...


Where DS:[ESI+ECX] is pointer to byte array.

How can I assign values like that in C++?
Posted

Something like:
C++
BYTE byteArry[24];
BYTE oneByte;

oneByte = byteArray[10];

If you mean actually setting a register value within a C++ program then you could do it within an __asm block as described here[^].
 
Share this answer
 
I meant something like:

dwKey is now equal to 0x4FFFAACC
And I want to change HIBYTE of that DWORD to 4C.
So It will be equal to 0x4FFF4CCC now
 
Share this answer
 
Comments
CPallini 17-Jun-10 6:49am    
Do you mean
dwKey = (dwKey & 0xFFFF00FF) | 0x00004C00;
?
From the assembly you've posted my Microsoft Intellisense paperclip leaps up and says: "Hey, it looks like you're wanting to set bytes in a 32 bit value! Do you want to do it with unions, bit-masks or disgusting casting?"

Starting with the disgusting casting... What you do is tell the compiler that the variable containing the 32 bit value is really an array of 4 bytes:

unsigned value;
char *p = reinterpret_cast<char>( &value );</char>


Then you can set the bytes as if they're members of a 4 element array p. This is a bit nasty as it requires an explicit cast and is playing with pointers. It also can't address smaller elements than a single byte. And you can address off the end of the array, very nasty.

Unions effectively overlay two (or more) interpretations of a bit pattern over a chunk of memory:

union byte_accessible_unsigned_int
{
    unsigned value;
    struct
    {
        unsigned char byte_1;
        unsigned char byte_2;
        unsigned char byte_3;
        unsigned char byte_4;
    } bytes;
};


You can then fiddle to your heart's content:

byte_accessible_unsigned_int r;

r.value = 0;

r.bytes.byte_2 = 0x04;

assert( r.value == 0x00000400 );


As you're used to x86 assembler you could represent a general register as:

union general_reg
{
    struct
    {
        unsigned char l;
        unsigned char h;
    } byte_regs;
    unsigned short x;
    unsigned long  e;
};


So...

general_reg eax;

eax.byte_regs.h = 0x01; // like setting AH
eax.e = 0x00FF00FF;     // like setting EAX


Note that this doesn't do anything with a hardware register, it just looks like one. It could be handy reading EAX after it's been pushed on the stack for instance.

Unions are pretty clean but may not be portable due to byte ordering - the C++ standard doesn't specify an order for bytes in an int.

That leaves bit field. What you do here is zero out all the bits in the byte you want to modify and then OR in the new bits:

unsigned value = 0xF0F0F0F0;

value &= 0xFFFF00FF;
value |= 0x00000F00;

assert( value == 0xF0F00FF0 );


This is probably the most portable way of doing things and it's pretty safe as well. AND you can set/reset/toggle individual bits as wel.

Generally you probably don't want to mess around with guff like this unless you're directly interfacing with hardware or programming something fairly limited like a pocket calculator. You can usually think of a better way of representing your data in C++ that doesn't involve mangling bits and addresses.

Cheers,

Ash
 
Share this answer
 
Comments
Im2N00By 16-Jun-10 16:40pm    
Thank you. I haven't thought about it this way. I was poking with shifting, but I don't like it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900