本文介绍了使用C ++设置寄存器的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

再次问好,

再一次,我有一个问题:
当我有->
MOV AL,BYTE PTR DS:[ESI + ECX]

MOV AH,...

MOV AX,...


其中DS:[ESI + ECX]是指向字节数组的指针.

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++?

推荐答案

BYTE byteArry[24];
BYTE oneByte;

oneByte = byteArray[10];


如果实际上是在C ++程序中设置寄存器值,则可以在__asm块中进行操作,如 [ ^ ].


If you mean actually setting a register value within a C++ program then you could do it within an __asm block as described here[^].



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



然后,您可以将字节设置为好像它们是4元素数组p的成员.这有点讨厌,因为它需要显式强制转换并正在使用指针.它也不能寻址比单个字节小的元素.而且,您可以解决数组末尾的问题,非常麻烦.

联合有效地将一个位模式的两个(或更多)解释覆盖在一块内存上:



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 );



当您习惯使用x86汇编程序时,可以将常规寄存器表示为:



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



请注意,这对硬件寄存器没有任何作用,只是看起来像一个.例如,将EAX推入堆栈后,可以很方便地读取EAX.

联合非常干净,但由于字节顺序而不能移植-C ++标准未指定int中字节的顺序.

剩下一点点的领域.您要做的是将要修改的字节中的所有位清零,然后在新位中进行或运算:



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 );



这可能是最便携的做事方式,也很安全.并且您可以设置/重置/切换单个位.

通常,除非您直接与硬件接口或对诸如袖珍计算器之类的功能进行限制编程,否则您可能不希望像这样乱七八糟.通常,您可以想到一种更好的用C ++表示数据的方式,该方式不涉及对位和地址的处理.

干杯,



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


这篇关于使用C ++设置寄存器的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 10:04