[YLUG] Help with c++ pointers - Please

Nicholas Thomas nick at lupine.me.uk
Sun Jan 13 11:59:09 GMT 2008


Dominic Hibbs wrote:
> POINTER HELP REQUESTED
>
> I am an assembly language programmer - I also program in many other 
> languages BUT, as many of you youngsters may not yet have learned, 
> Knowledge has a short shelf life and my C/C++ has been on the shelf 
> too long.
> In this - "long int" means 64 bit.
>
> In assembly language there is no typing at all.  A 32 bit quantity may be
> 1. an integer,
> 2. a sixteen bit number followed by a byte with no defined value and a
>     character,
> 3. half of a double,
> 4. four bytes of program.
> 5. a pointer to something,
> 6. or a pointer to a pointer
> and it is up to the programmer how something is interpreted and what 
> alignment is used.
>
> I am converting a program, written in assembler to C/C++ and I am 
> stuck over pointers. This data structure is a linked list of variables.
>
> A block of memory consists of records made up of
>
> Byte No. Content
> (0..7)     a 32 bit pointer to
>                 a long int (8 Byte)
>                 or a double
>         or (32 bit pointer and two 16 bit integers)
> (8..15)     followed by one byte made up of
>         2 bits of flags, 4 bits of a number and two more bit flag
>         followed by an ASCIZ string of 4 n + 3 bytes long (n = 0..30)
> (16..23) followed by a long int or Double
>         or (32 bit pointer and two 16 bit integers)
>
> Bits 8..15 are anded with  & 0x00 00 00 3c and then added to the 
> address of this record to get the next record.
>
> First variable is a long int called "ten" and has the value 10 so the
> first two bits of byte 8 hav the value 0b01 and the record length is 20
> bytes the other two bit flags have the value 0b01 (0 means Not an array
> and the 1 bit says this variable has been initialised).
>
> Abit of (obviously incorrect) code follows:
>
>     char * s = "ten";
>     void * blockaddr = malloc(varspace);  // Check return value for NULL
>     recptr = blockaddr;       // get address of first record
>     * recptr = * recptr + 16; // insert into memory at blockaddr
>                       // blockaddress + 16
>     recptr += 8;          // pointer arithmetic point to byte 8
>
>     * recptr = 1 | 20 | 0x80  // two bit flags | record length |
>                                   // initialised as a byte value
>     recptr++;
>     *recptr++ = *s;      // recptr is a char *
>     char ch;    
>     do {
>                *recptr++ = ch = * (++ s);
>     } while( ch);
>     recptr +=3;               // align on four byte -
>                                   // we are at the start of the next 
> record.
>
>   
Urgh. Ouch. Eeep. Tell me, is there any particular reason you need to 
emulate the program's memory allocation behaviour so precisely? If this 
were me, I'd be looking at using (probably) std::list, containing either 
a (fairly) simple class or a struct/union thingy (which I haven't used 
for ages). Trying to literally convert an ASM program to C/C++ sounds 
like a lesson in pain (why not just use asm { ... } in that case? ;) ).

Also, you can't guarantee that long int is 64 bits. As an example:
<lupine_85> geordi: {long int i; cout << sizeof(i); }
<geordi> 4
<lupine_85> geordi: {long long i; cout << sizeof(i); }
<geordi> ISO C++ does not support 'long long'
<lupine_85> geordi: {long long int i; cout << sizeof(i); }
<geordi> ISO C++ does not support 'long long'

If you have <stdint.h>, you can use uint64_t (or int64_t) instead.

/Nick




More information about the York mailing list