pazzle for profi

User avatar
Privet
Администратор
Posts: 17200
Joined: 03 Jan 1999 10:01
Location: Redmond, WA

pazzle for profi

Post by Privet »

Пишем два модуля.Компилируем раздельно

Первый:

// global
char data[8] = { 0x68, 0xB8, 0x03, 0x00, 0x24 0x00, 0x00. 0x00 }
................................................................................................
Второй:

typedef struct {
int a;
int b;
i} u;

extern char data[8];

void* p = (void*)data;
int x = (u*)(p)->a; // Результат: x = 0x 00 00 B8 68
int y = (u*)(p)->b; // Результат: y = 0x 00 03 00 24

Оба компилируются с совершенно одинаковыми компю ключами. компилятор тот же самый - RealView (RVCT) Возможно, некоторые нстройки (-D_VALUE -D_VALUE2) отличаются.

Что бы это могло быть?

Такая конструкция работает правильно:

int z;
memcpy((void*)&z,Data, sizeof(int)); // Результат: z = 0x 68 B8 03 00


Идеи, предложения?
Привет.
dB13
Уже с Приветом
Posts: 1494
Joined: 08 May 2001 09:01
Location: Silicon Valley

Post by dB13 »

Pass an option to the compiler to output ASM file or disassemble the executable/obj file. Look at the generated code.

What kind of CPU are you using? PPC, ARM? Is data[] located in normal RAM
and not in a peripheral device 3 weird busses from the CPU?
DmitryMA
Уже с Приветом
Posts: 783
Joined: 20 May 2002 00:52
Location: Israel-->Boston, USA

Post by DmitryMA »

Часть переменных определена как char (1 byte), часть как int (2 or 4 bytes). Это создает проблемы с преобразованиями одного типа в другой. Попробуйте определить все как int.
Демократия измеряется расстоянием, которое может пройти гражданин без предъявления удостоверения личности.
111001
Posts: 11
Joined: 04 Apr 2004 01:40

Re: pazzle for profi

Post by 111001 »

Privet wrote: Идеи, предложения?

а что напечатается, если прогнать один модуль
( int x = (u*)(p)->a ; выглядит как ошибка - see operator precedence...
есть другие опечатки в исходном коде,
и чтобы проверить sizeof-s, offset-s, alignment для вашего компилятора)

Code: Select all

#include <stdio.h>

unsigned char data[8] = { 0x68, 0xB8, 0x03, 0x00, 0x24, 0x00, 0x00, 0x00 };


typedef struct { int a; int b; } U;


int main()
{
  U * u0 = (U*)0;

  printf( "\nsizeof(U)=%d, sizeof(int)=%d, offset_a=%d, offset_b=%d\n",
    sizeof(U), sizeof(int), (int) & (u0->a), (int) & (u0->b)  );

  printf("\ndata[] = {0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x};\n",
    data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7] );

  {
    void* p = (void*)data;
    int x = ((U*)p)->a;
    int y = ((U*)p)->b;
    printf("\nx=0x%08x\ny=0x%08x\n", x, y);
  }
  return 0;
}

?
Last edited by 111001 on 05 Jun 2004 17:31, edited 2 times in total.
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

Во первых есть у меня предчуствие что дело не в том что модули разные. Опрделите массив байтов в том же модуле и посмотрите будет ли наблюдаться эффект.

Во вторых преобразование байтов в int зависит от аппаратоной платформы, есть big endian & little endian, есть выравнивание структур на границу 4-х байт. Возможно в этом дело. Попробуйте подойти к проблеме с другой стороны.
struct u uu;

uu.a = 0x0102;
uu.b= 0x0304;

а теперь привести это дело к массиву байт и распечать.

Возможно выходом будет использование htons()
Никакой разрухи нет. (с) Проф. Преображенский.
DmitryMA
Уже с Приветом
Posts: 783
Joined: 20 May 2002 00:52
Location: Israel-->Boston, USA

Post by DmitryMA »

Вот такой код

Code: Select all

#include "stdafx.h"
// global
extern char data[];

int _tmain(int argc, _TCHAR* argv[])
{
   typedef struct {
      int a;
      int b;
   } u;
   void* p = (void*)data;
int x = ((u*)(p))->a; // Результат: x = 0x0003b868
int y = ((u*)(p))->b; // Результат: y = 0х24
   return 0;
}


Результат: x = 0x0003b868
Результат: y = 0х24


что вполне соответствует действительности, учитывая, что порядок байтов на Интел-платформах - "обратный"

Борис, обратитет внимание на возможную вашу ошибку (у меня - лишняя пара скобок):

int x =( (u*)(p) ) ->a;
int y =( (u*)(p) ) ->b;

Компилятор - Visual Studio .Net, OS: WIN XP
Демократия измеряется расстоянием, которое может пройти гражданин без предъявления удостоверения личности.

Return to “Вопросы и новости IT”