Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
10/27/03 03:01
Read: times


 
#57288 - RE: Weekend Puzzler #1
Responding to: ???'s previous message
This Puzzler came to mind when I was writing some 8051 C code which needed to perform the same functions as in the Puzzler diagram. I have reduced the C code to a pair of bare bones subroutines. The first C subroutine which performs the function as depicted in the first part of the Puzzler diagram is as shown below:

unsigned char x;

void boo(unsigned char d)
{
    x = (x & 0xF0) | (d & 0xF);
}

During a debugging session I noticed that the code produced by the compiler for logic such as in the boo() subroutine was more complex that I had expected. From long past experience I was aware of the XCHD instruction and I knew that if I had written boo() in assembly language that I would have used this instruction. Here is the compiler generated code for boo(). R7 is the generic entry parameter register used for an subroutine like this.

BOO:
    MOV     A,R7
    ANL     A,#0FH
    MOV     R7,A
    MOV     A,x
    ANL     A,#0F0H
    ORL     A,R7
    MOV     x,A
    RET     

Continuing on this investigation I also had written come C code for handling the high nibble as shown in the second part of the Puzzler diagram. I boiled this one down into a simple C subroutine called foo():

unsigned char x;

void foo(unsigned char d)
{
    x = (x & 0xF) | (d << 4);
}

Also curious to see how clever the C compiler would be to generate the code I captured the compiler output as source from the Keil C-51 compiler. Here is the resulting code (noting once again that the compiler has the entry argument for the subroutine in R7):

FOO:
    MOV     A,R7
    SWAP    A
    ANL     A,#0F0H
    MOV     R7,A
    MOV     A,x
    ANL     A,#0FH
    ORL     A,R7
    MOV     x,A
    RET     

As you can see the compiler has translated the C code to assembler a straightforward and logical way to address the nibble move functions.

Now it is not particularly surprising that the compiler did not try to use the XCHD instruction since it is a limited scope instruction. Over the course of my experience I have come to know that C compilers often do not use all the opcodes in a processor's instruction set.

One thing led to another and one day I realized that it was just a little strange that Intel included the XCHD opcode into the 8051 design for managing the low nibble in such a short and concise manner, while not providing the same functionality to provide a swap of the low nibble of A with the high nibble of a target memory byte. One can only guess at this point as to why things ended up the way they did.

I looked at the implementation of the high nibble exchange using assembly language and noticed that there were multiple ways to code it, including starting with the type of code generated by the C compiler. After looking at it for some time I ended up with the same code that Felix Diaz posted earlier in this thread.

I also liked the solution posted by Kai Klaas. I decided to look and see if there was any particular advantage in terms of run time performance of ending the code sequence with the XCH instruction over the MOV instruction. It turns out that there is no performance change as the two instructions execute in the same time period and are both one byte of opcode. I made a little chart showing the bytes & clocks for a Cygnal processor and an Intel standard flavor 8051.
Instruction   Cygnal C8051F226    Intel 87C51FA
Code Used      Bytes   Clocks      Bytes  Clocks
------------  ----------------    --------------
SWAP A           1        1          1      12
XCHD @R0, A      1        2          1      12
XCH A, @R0       1        2          1      12
MOV A, @R0       1        2          1      12


Thanks to all that took part in this weekend's Puzzler.
Michael Karas



List of 17 messages in thread
TopicAuthorDate
Weekend Puzzler #1            01/01/70 00:00      
   RE: Weekend Puzzler #1            01/01/70 00:00      
      RE: Weekend Puzzler #1            01/01/70 00:00      
   RE: Weekend Puzzler #1            01/01/70 00:00      
      RE: Weekend Puzzler #1            01/01/70 00:00      
         RE: Weekend Puzzler #1            01/01/70 00:00      
   RE: Weekend Puzzler #1            01/01/70 00:00      
   RE: Weekend Puzzler #1            01/01/70 00:00      
      RE: Weekend Puzzler #1, to Kai Kaas            01/01/70 00:00      
         RE: Weekend Puzzler #1, to Kai Kaas            01/01/70 00:00      
      RE: Weekend Puzzler #1            01/01/70 00:00      
         RE: Weekend Puzzler #1 / Asok            01/01/70 00:00      
            RE: Weekend Puzzler #1 / Asok            01/01/70 00:00      
   RE: PIC Solution            01/01/70 00:00      
      RE: PIC Solution, to Mahmood            01/01/70 00:00      
         RE: PIC Solution, to Mahmood            01/01/70 00:00      
      RE: PIC Solution, to Mahmood            01/01/70 00:00      

Back to Subject List