Solved

16 bit access to 8 bit data non-aligned data

Posted on 2002-03-19
14
163 Views
Last Modified: 2010-04-15
Given the code at the end of this question, is it possible to replace the two macros: getWord() and setWord() with a single program element that can appear on either side of an assigment operator?

i.e.

where I now have:
  i = getWord(a)
  i++;
  setWord(a,i);

I want to be able to have something like:
  word(a) = word(a)+1;

Or even better
  word(a)++;

Is it possible to reduce the two macros to one program element?
- I don't have the luxury of using C++ :(
- It doesn't have to be a macro.
- Be as creative as you like
- The important conditions to remember are:
  1. The dataArea array must be an array of unsigned char with no specific WORD alignement.
  2. The appliation must be able to function transparently on processors that use different byte ordering. i.e. Little endian or big endian.
- If you're feeling mighty clever, I also require the same functionality for DWORDS (4 byte unsigned longs). Although that should be a natural extension of the solution for WORD (2 byte unsigned shorts).

Thanks for your time
Paul

#include <stdio.h>

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  ADDR;

#define getWord(a)   (WORD)((*(dataArea+a)<<8)|*(dataArea+a+1))
#define setWord(a,v) (*(dataArea+a)=((v)>>8)&0xff,*(dataArea+a+1)=(v)&0xff)

BYTE dataArea[] = {
  0x01,0x23,0x45,0x67,0x89,0xAB
};

int
main(int argc, char *argv[])
{
  ADDR     addr=1;
  WORD     i;

  i = getWord(addr);
  printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd)\n",addr,i,i);
  setWord(addr,1234);
  i = getWord(addr);
  printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd)\n",addr,i,i);

  return 0;
}
 
0
Comment
Question by:zebada
  • 6
  • 5
  • 2
  • +1
14 Comments
 
LVL 6

Author Comment

by:zebada
Comment Utility
I just re-read the question - gee it sounds a lot like a homework assignment.

So before anyone gets upset I'll explain why I need this:

I am upgrading the string handling on a virtual machine. Currently the strings have a limit of 127 characters. That limit can easily be stored in a single byte so getting and setting the string length is as simple as setting up a macro that computes the char * of the string length.

The string handling is being upgraded to handle strings longer than 256 characters. The length obviously needs to use more than 1 byte. So my problem is:

How do I easily upgrade the virtual machine which has hundreds of functions with thousands of references to the string length as a macro. The macro is found wherever a char * can be found - including on the left of an assignment operator.

sombody put me out of my misery :(
Paul
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
You're probably gonna hate me for that, but... well, lets see what you think of

#include <stdio.h>

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  ADDR;

#define WORDREF(a)   ((WORD*)(dataArea+a))

BYTE dataArea[] = {
 0x01,0x23,0x45,0x67,0x89,0xAB
};

int
main(int argc, char *argv[])
{
 ADDR     addr=1;
 WORD     i;

 i = *WORDREF(addr);
 printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd)\n",addr,i,i);
 *WORDREF(addr)=1234;
 i = *WORDREF(addr);
 printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd)\n",addr,i,i);

 return 0;
}
0
 
LVL 6

Author Comment

by:zebada
Comment Utility
If only it were that simple.

It's the little endian/big endian thing that will cause that approach to fail.
I've added to the printf() to display the actual data bytes in the dataArea array like so:

printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd) DataArea=[0x%02x,0x%02x]\n",addr,i,i,dataArea[1],dataArea[2]);

The output of my sample program is:
Value of WORD at Address 0x00000001 is 0x2345 (9029) DataArea=[0x23,0x45]
Value of WORD at Address 0x00000001 is 0x04d2 (1234) DataArea=[0x04,0xd2]

The output of your sample program is:
Value of WORD at Address 0x00000001 is 0x4523 (17699) DataArea=[0x23,0x45]
Value of WORD at Address 0x00000001 is 0x04d2 (1234) DataArea=[0xd2,0x04]

This is really the root of the problem.

It is also a completely acceptable for the solution to use #ifdef's because I will always have a different executable file for different cpu architectures.

Paul
0
 
LVL 5

Expert Comment

by:BlackDiamond
Comment Utility
how about changing it to

#define WORDREF(a) ntohl(((WORD*)(dataArea+a)))



0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>#define WORDREF(a) ntohl(((WORD*)(dataArea+a)))

a) would have to read

#define WORDREF(a) ntohs(*((WORD*)(dataArea+a)))

b) doesn't make sense, as these functions work based on the architecture the app is running on not on the architecture the app is emulating

c) is pretty equivalent to what he already has, as it can't serve as a lvalue...
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
But, however, BlackDiamond, you gor me in gear :o)

What about

#include <stdio.h>

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  ADDR;

#define WORDREF(a)   ((WORD*)(dataArea+a))

BYTE dataArea[] = {
0x01,0x23,0x45,0x67,0x89,0xAB
};

#ifdef __LITTLE_ENDIAN__
#define __WORD ( x) ( (x >> 8) | ((x & 0x00FF) << 8 )
#else
#define __WORD ( x) ( x)
#endif

int
main(int argc, char *argv[])
{
ADDR     addr=1;
WORD     i;

i = __WORD( *WORDREF(addr));
printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd)\n",addr,i,i);
*WORDREF(addr)=__WORD(1234);
i = __WORD( *WORDREF(addr));
printf("Value of WORD at Address 0x%08lx is 0x%04hx (%hd)\n",addr,i,i);

return 0;
}
0
 
LVL 6

Author Comment

by:zebada
Comment Utility
Neat idea, but it doesn't get me any closer to than I already am.

I still can't use the same macro on both sides of the assignment operator.

That means I need to go through the code and edit ALL instances of the exiting single (char *) macro that currently CAN and DOES appear on both sides of an assignment operator.

Because (char *) is ALWAYS the same no matter what the cpu architecture it can be used as both l-value and r-value.

Maybe it's not possible with multibye integers.

0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>Maybe it's not possible with multibye integers.

Afford the luxory to use C++ and it's a matter of minutes to find a soultion :o)
0
 
LVL 6

Author Comment

by:zebada
Comment Utility
Oh, how I've dreamed of being able to write this VM in C++. :-(

Don't forget I am at liberty to change the format of the dataArea[] array. That's essentially the object code format.
However it must be the same for both architecture types to provide 100% cross-platform portability.
0
 
LVL 6

Author Comment

by:zebada
Comment Utility
Just in case you're interested - I solved the problem by dynamically modifying the "object code" when it is loaded into the virtual machine. The object code is changed so that anywhere 2, 4 or 8 byte integers are used they are converted to the endian of the current processor.

I am going to delete this question.
0
 
LVL 1

Expert Comment

by:Computer101
Comment Utility
A request for deletion has been made.  If no objection, I will place this in PAQ

Computer101
E-E Admin
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
I'd say, there are some nice tricks shown in here, why not PAQ (even @0)?
0
 
LVL 1

Accepted Solution

by:
Computer101 earned 0 total points
Comment Utility
Points refunded and placed in PAQ

Computer101
E-E Admin
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Hey, at 0 points, you could have given me the "answer" :o)
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now