nor1675@dsacg2.UUCP (Michael Figg) (03/01/89)
----------------------------------------------------------------- Following is the relevent piece of code from a dump routine I have been trying to write on an Amiga. I'm trying to pass a pointer to a variable that I want to dump in hex and the number of bytes to print: . . long test_long; test_long = 1234; print_data((char *)&test_long,sizeof(test_long)); . . void print_data(pnt,num) char *pnt; int num; { int i; for(i = 0; i < num; i++) { printf("%02x",*(pnt + i)); } } . What I would hope to get from this is '000004d2' but actually got '000004ffffffd2'. This was done with Lattice v5.0.1. I also tried similar code at work on a PC with MS v5.1. There I got 'ffd2040000', which except for the leading 'ff' looks like it was printing the bytes backwards. Any clues as to why I'm getting this output and how to do it right? Thanks ->Mike<- -- "Hot Damn! Groat Cakes Again Michael Figg Heavy on the thirty weight!" DLA Systems Automation Center Columbus, Oh. (614)-238-9036
byrum@cs.odu.edu (Terry Franklin Byrum) (03/01/89)
Try this instead... void print_data(pnt,num) unsigned char *pnt; int num; { int i; for(i = num - 1; i >= 0; i--) printf("%02x ",*(pnt + i)); } > ... There I got 'ffd2040000', which except for the leading 'ff' looks > like it was printing the bytes backwards. Any clues ... Have you ever heard of low-high (Little Endian) architecture. Most PC type computers store values least significant byte first. If you want a number written (normally) you must scan backwards. Also, on most PC machines char is signed by default. Due to sign extension, if the byte value is greater than 7F Hex, unwanted leading FFs will appear on promotion to int. The solution is to specify unsigned char* instead of char*, either as the function's formal parameter or as a cast within the printf argument. ... Frank Frank Byrum, BROOKS Financial Systems, Suffolk VA, (804)539-7202 1st Law of SE INET:byrum@cs.odu.edu UUCP:..!sun!xanth!{byrum,brooks!frank} Semper Sic Factum -- Inventions have long since reached their limit -- and I see no hope for further developments. - Julius Frontinus, world famous engineer, Rome, 10 AD | Terry Franklin (Frank) Byrum | BROOKS Financial Systems, Inc. ___ | INET: byrum@cs.odu.edu /__ _. __. _ _ /_ | UUCP: ...!sun!xanth!brooks!byrum / _/ \_(_/|_|\|_/ \ | DISCLAIMER: No one listens anyway!
piet@ruuinf (Piet van Oostrum) (03/02/89)
In article <652@dsacg2.UUCP>, nor1675@dsacg2 (Michael Figg) writes:
` .
` long test_long;
` test_long = 1234;
` print_data((char *)&test_long,sizeof(test_long));
` .
` void print_data(pnt,num)
` char *pnt;
` int num;
` {
` int i;
` for(i = 0; i < num; i++)
` {
` printf("%02x",*(pnt + i));
` }
` }
Any clues as to why I'm getting this output and how to do it
` right? Thanks
The problem is that this code is highly unportable. So what you get depends
very much on the machine/compiler you have. There are two problems:
1. The ENDIAN-NESS of the machine. This means whether the bytes in a long
are addressed from the most significant byte or from the least
significant byte. What you are doing is taking a long and getting bytes
out of it. On a BIG-ENDIAN machine (such as the 68000) the first byte
you get is the upper (most significant) one, on a SMALL-ENDIAN (like the
8086) it is the lower byte. This explains the difference between the
Amiga and MS-DOS.
2. The char type that your compiler has. This can be signed or unsigned
(old compilers usually have only signed. In your case both compilers
apparently have signed chars, which means that a char that has its
8th bit set is passed to printf as a negative integer, which cuases
printf to print extra ff's (how many depends on the size of int, which
-- not surprisingly -- is 4 bytes on the Amiga and 2 bytes on MS-DOS).
This problem is easily solved by
printf("%02x",*(pnt + i) & 0xff);
or
printf("%02x",pnt[i] & 0xff);
--
Piet van Oostrum, Dept of Computer Science, University of Utrecht
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands
Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!hp4nl!ruuinf!piet)
edwin@hcr.UUCP (Edwin Hoogerbeets) (03/04/89)
In article <652@dsacg2.UUCP> nor1675@dsacg2.UUCP writes: >I'm trying to pass a pointer to a variable >that I want to dump in hex and the number of bytes to print: > > long test_long; > test_long = 1234; > print_data((char *)&test_long,sizeof(test_long)); > void print_data(pnt,num) > char *pnt; > int num; > { > int i; > for(i = 0; i < num; i++) > { > printf("%02x",*(pnt + i)); > } > } Your problem is that *(pnt + i) has type char. Thus, a char is pushed onto the stack and printf is called, right? Well, not really. First, the char is promoted to a int, which under Lattice is 32 bits. But wait! A char is a signed quantity, so the promotion dutifully sign extends the char. Any character >= 128 has the high bit set, and this bit gets copied during sign extension. You got "000004ffffffd2" because the "d2" has the high bit set (and extended in the call to printf) while the other bytes don't have the high bit set. Your solution is simple: Change your argument declaration to unsigned char *pnt; or better yet, register unsigned char *pnt; How's that for a declaration! Happy hacking, Edwin HCR co-op subterfuge team