Date: Mon, 31 Aug 1998 12:00:08 +0300 (IDT) From: Eli Zaretskii To: Endlisnis cc: djgpp AT delorie DOT com Subject: Re: Am I retarded -or- Why is my exe size so big?!? In-Reply-To: <35E980D9.2EB7A55D@unb.ca> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk On Sun, 30 Aug 1998, Endlisnis wrote: > > compute the linear address with seg*16 + offset. > > But, if I do that, then I will get an overflow when > multiplying 'seg' by 16. And I will loose the top 4-bits of the > address. You need to promote it, of course: ((int)seg * 16) + offset. The linear address is 32-bit anyway, so it doesn't matter when to convert it to an int. > typedef unsigned int lword; > > lword a; > short* b; > > a = (lword)(short*)a; > b = (short*)(lword)b; > > AFAIK: These 2 lines should do NOTHING (the values of a,b should not > change at all). Of course, they don't. Casting alone usually doesn't do anything. But your original code didn't just cast. It shifted bits and used addition and bitwise AND operations. That is something different indeed. > Given that, I don't understand why that line of code I posted earlier > wouldn't do what I expected and would encourage anyone to give me any lengthy > expanation they have. Your code is wrong for several reasons, which I describe below. But the point I wanted to make in my previous message was that your *approach* is wrong: you use pointers to do arithmetics on integers (the segment and the offset of a real-mode pointer). It is true that pointers in DJGPP are just offsets, so they are 32-bit integers. But using them for integer computations is a bad idea which will easily get you into trouble; and it certainly defeats many useful diagnostics that the compiler could emit to help you (since you are coerced to use type-casts to work around the compiler). If you need to compute a*16+b, just do it (by declaring two shorts); do NOT try to pack them into a single pseudo-pointer and then shuffle the bits around. Now to the problems with your code: - This line: DOS = (short*)(((lword)DOS>>12)&0xFFFF0)+((lword)DOS&0xFFFF); boils down to an expression like this: DOS = (short *)a + b; However, adding b to a pointer to a short actually adds 2*b to the value of the pointer, because a short is 2 bytes wide. You need to change this line to something like this: DOS = (short *)(a + b); or, returning to your code: DOS = (short*)((((lword)DOS>>12)&0xFFFF0)+((lword)DOS&0xFFFF)); - The second problem is that your cout line is wrong: cout << DOS << " should be 0xC1234\n"; It should say something like this instead: cout << hex << (lword)DOS << " should be 0xC1234\n"; After these two changes, the program works for me as expected, under any level of optimizations. But I still think it is a very bad idea to do it this way.