Compiler generated code
-
Can someone explain to me why for the following code
memcpy(&PSW+8,holdptr,8);
memcpy(&PSW,holdptr,8);
00007FF655264C1D mov rax,qword ptr [rbx+4]
00007FF655264C21 mov qword ptr [rbp+3F0h],raxmemcpy(&PSW+8,holdptr,8);
00007FF655264C28 mov rax,qword ptr [rbx+0Dh]
00007FF655264C2C mov qword ptr [rbp+530h],raxThe compiler generate a displacement of Hex 140 from the structure PSW instead of 8
struct {
BYTE sysmask; /* System mask (0 - 7) */
BYTE pkey; /* PSW Key (8 - 11) */
BYTE states; /* EC,M,W,P bits (12 - 15) */
BYTE asc; /* Address space control */
/* (16 - 17) */
BYTE cc; /* Condition code (18 - 19) */
BYTE progmask; /* Program mask (20 - 23) */
BYTE zerobyte; /* Zeroes (24 - 31) */
/* or (esame) (24 - 30) */
u_int /* Addressing mode (31 - 32) */
amode64:1, /* 64-bit addressing (31) */
amode:1, /* 31-bit addressing (32) */
zeroilc:1; /* 1=Zero ILC */
char zeroword[4]; /* esame only (33 - 63) */
char ia[16]; /* Instruction addrress */
/* (33 - 63) */
/* or (esame) (64 -127) */
char amask[4]; /* Address wraparound mask */
char intcode[2]; /* Interruption code */
BYTE ilc; /* Instruction length count */
BYTE unused;
} PSW; -
Can someone explain to me why for the following code
memcpy(&PSW+8,holdptr,8);
memcpy(&PSW,holdptr,8);
00007FF655264C1D mov rax,qword ptr [rbx+4]
00007FF655264C21 mov qword ptr [rbp+3F0h],raxmemcpy(&PSW+8,holdptr,8);
00007FF655264C28 mov rax,qword ptr [rbx+0Dh]
00007FF655264C2C mov qword ptr [rbp+530h],raxThe compiler generate a displacement of Hex 140 from the structure PSW instead of 8
struct {
BYTE sysmask; /* System mask (0 - 7) */
BYTE pkey; /* PSW Key (8 - 11) */
BYTE states; /* EC,M,W,P bits (12 - 15) */
BYTE asc; /* Address space control */
/* (16 - 17) */
BYTE cc; /* Condition code (18 - 19) */
BYTE progmask; /* Program mask (20 - 23) */
BYTE zerobyte; /* Zeroes (24 - 31) */
/* or (esame) (24 - 30) */
u_int /* Addressing mode (31 - 32) */
amode64:1, /* 64-bit addressing (31) */
amode:1, /* 31-bit addressing (32) */
zeroilc:1; /* 1=Zero ILC */
char zeroword[4]; /* esame only (33 - 63) */
char ia[16]; /* Instruction addrress */
/* (33 - 63) */
/* or (esame) (64 -127) */
char amask[4]; /* Address wraparound mask */
char intcode[2]; /* Interruption code */
BYTE ilc; /* Instruction length count */
BYTE unused;
} PSW;You need to go and review C/C++ pointer arithmetic :-) Your pointer arithmetic asks it to do that .... you must have your warnings turn way down because really it should give a warning. Since it is has escaped you, specifically what you have asked it to do is add 8 times the size of PSW to the pointer to PSW which is what it did. For some reason your expect byte operation on a pointer that isn't a pointer to a byte. If you wanted a byte operation then cast the pointer to a byte. I can't make head nor tails of what appears to be bitcount numbers. I warn you that you need pack(1) for that, and even if packed those bitcounts don't match. It looks like some of the bit fields need unions because there seems to be variants. I assume you were trying to point at the 8th byte in the struct but without packing it isn't guaranteed you will get what you expect. I strongly recommend you put the bitpacks in a struct so it's named and then set the pointer to the named element in the struct. It would be a whole lot easier to pack that structure exactly as whatever those bitcounts you are writing because it seems like it's a real thing ... So make the struct match reality. This is my best guess what your struct is supposed to be and I have used the proper standard C/C++ types, it is ill advised to do such precise packing on user defined types like BYTE. C/C++ standard file stdint.h is your friend use it when not on Windows/Linux API. The uint8_t will cast to everything properly as C knows exactly what it is.
#include // I am going to check packing at compile time (generates no code)
#include // This defines bool we will need it if not included already
#include // C standard for fixed width types we want uint8_t .. we need to included if not already
#pragma pack(push, 1)
struct psw_s { // Named the struct for compile time checks
union {/\* Variant 1 structure of first 128 bits \*/ struct variant1 { uint8\_t sysmask; /\* System mask (0 - 7) \*/ uint8\_t pkey; /\* PSW Key (8 - 11) \*/ uint8\_t states; /\* EC,M,W,P bits (12 - 15) \*/ /\* guessing you want an Anonymous struct to match bit count on byte 3 \*/ struct byte3\_fields { uint8\_t asc : 2; /\* Address space control (16 - 17) \*/ uint8\_t cc : 2; /\* Condition code (18 - 19) \*/ uint8\_t progmask : 4; /\* Program mask (20 - 23) \*/ }; /\* best guess at variant unions needed to match bit count on byte 4 \*/ union { uint8\_t zer
-
Can someone explain to me why for the following code
memcpy(&PSW+8,holdptr,8);
memcpy(&PSW,holdptr,8);
00007FF655264C1D mov rax,qword ptr [rbx+4]
00007FF655264C21 mov qword ptr [rbp+3F0h],raxmemcpy(&PSW+8,holdptr,8);
00007FF655264C28 mov rax,qword ptr [rbx+0Dh]
00007FF655264C2C mov qword ptr [rbp+530h],raxThe compiler generate a displacement of Hex 140 from the structure PSW instead of 8
struct {
BYTE sysmask; /* System mask (0 - 7) */
BYTE pkey; /* PSW Key (8 - 11) */
BYTE states; /* EC,M,W,P bits (12 - 15) */
BYTE asc; /* Address space control */
/* (16 - 17) */
BYTE cc; /* Condition code (18 - 19) */
BYTE progmask; /* Program mask (20 - 23) */
BYTE zerobyte; /* Zeroes (24 - 31) */
/* or (esame) (24 - 30) */
u_int /* Addressing mode (31 - 32) */
amode64:1, /* 64-bit addressing (31) */
amode:1, /* 31-bit addressing (32) */
zeroilc:1; /* 1=Zero ILC */
char zeroword[4]; /* esame only (33 - 63) */
char ia[16]; /* Instruction addrress */
/* (33 - 63) */
/* or (esame) (64 -127) */
char amask[4]; /* Address wraparound mask */
char intcode[2]; /* Interruption code */
BYTE ilc; /* Instruction length count */
BYTE unused;
} PSW;&PSW
is of type "pointer to PSW", so&PSW+8
would have the same value as(PSW *)((byte *)&PSW + 8 * sizeof(PSW))
The old C pointer rules live on! Cheers, PeterSoftware rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
-
You need to go and review C/C++ pointer arithmetic :-) Your pointer arithmetic asks it to do that .... you must have your warnings turn way down because really it should give a warning. Since it is has escaped you, specifically what you have asked it to do is add 8 times the size of PSW to the pointer to PSW which is what it did. For some reason your expect byte operation on a pointer that isn't a pointer to a byte. If you wanted a byte operation then cast the pointer to a byte. I can't make head nor tails of what appears to be bitcount numbers. I warn you that you need pack(1) for that, and even if packed those bitcounts don't match. It looks like some of the bit fields need unions because there seems to be variants. I assume you were trying to point at the 8th byte in the struct but without packing it isn't guaranteed you will get what you expect. I strongly recommend you put the bitpacks in a struct so it's named and then set the pointer to the named element in the struct. It would be a whole lot easier to pack that structure exactly as whatever those bitcounts you are writing because it seems like it's a real thing ... So make the struct match reality. This is my best guess what your struct is supposed to be and I have used the proper standard C/C++ types, it is ill advised to do such precise packing on user defined types like BYTE. C/C++ standard file stdint.h is your friend use it when not on Windows/Linux API. The uint8_t will cast to everything properly as C knows exactly what it is.
#include // I am going to check packing at compile time (generates no code)
#include // This defines bool we will need it if not included already
#include // C standard for fixed width types we want uint8_t .. we need to included if not already
#pragma pack(push, 1)
struct psw_s { // Named the struct for compile time checks
union {/\* Variant 1 structure of first 128 bits \*/ struct variant1 { uint8\_t sysmask; /\* System mask (0 - 7) \*/ uint8\_t pkey; /\* PSW Key (8 - 11) \*/ uint8\_t states; /\* EC,M,W,P bits (12 - 15) \*/ /\* guessing you want an Anonymous struct to match bit count on byte 3 \*/ struct byte3\_fields { uint8\_t asc : 2; /\* Address space control (16 - 17) \*/ uint8\_t cc : 2; /\* Condition code (18 - 19) \*/ uint8\_t progmask : 4; /\* Program mask (20 - 23) \*/ }; /\* best guess at variant unions needed to match bit count on byte 4 \*/ union { uint8\_t zer