[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