Monday, August 24, 2009

Puzzler #1


unsigned char x = 0x80;

main (void) {
char y;

y = 0x80;
if (x != y) {
printf("This should not happen\n");
}
}


Why does the string "This should not happen" appear on the console? It does on VS2005 for x86, but may not on a 8051 processor.

Answer: The problem is that 'char' and 'unsigned char' are different when it comes to comparisons, and that compilers like to optimize the comparison using machine register sizes. C casts the operands to machine sizes: unsigned char 0x80 gets cast to 0x00000080, and signed char 0x80 gets cast to 0xFFFFFF80. Then when you compare them, they don't equate! ARGH....

Thursday, August 20, 2009

Using Bits in 8051 assembly

warning: this is a placeholder written from memory. I need to update it



Useful commands: The JB (Jump if Bit set) will jump if a bit is set. The encoding of the field is the bit offset from data memory address 0x20. If you forget this, and try encoding the bit directly, then you will actually get bit 0x20.0 + 0x20 = 0x24.0 (ie 32 bits down the line).

To declare the bit in ASM:


BSEG 0 ; offset 0 in the 0x20.0 to 2F.7 range.
BIT mybit ; declare mybit at 0x20.0
...

; useful 8-byte entry in the vector table (ie at offset 0x0003 in code space for an ISR)

CSEG AT 0x0003

JB mybit, passhop ; 3 bytes encoding
AJMP fail ; 2 bytes encoding
passhop: LJMP pass ; 3 bytes encoding = 8 bytes total



In C, you would declare the bit as:

extern bit myBit at 0x20;

How to read high resolution system time in Win32


// example of how to read the system clock.
SYSTEMTIME st;
::GetSystemTime(&st);
FILETIME ft;
::SystemTimeToFileTime(&st,&ft);
DWORD diff = ft.dwLowDateTime - lasttime;
double rate;
rate = DEF_BUF_SIZE * 1000.0 / (diff * 1e-7) ;
std::cout << " rate:" << rate << std::endl;
lasttime = ft.dwLowDateTime;