Technical Tip of the `Month' MOVX A,@Ri and MOVX @Ri,A The 8031 has two rather mysterious instructions. These instructions are seldom understood and almost never used. They have the potential to speed up accesses to external memory significantly in certain circumstances. The instructions are MOVX A,@Ri and MOVX @Ri,A. At first look, these instructions don't seem to make sense. How can we use a register as an index into external memory? Registers are 8-bits and we need a 16-bit pointer to access external memory, right? Intel states in their 8-Bit Embedded Controllers databook that ``@Ri'' means ``8-bit internal RAM location (0-255) addressed indirectly through register R1 or R0.'' This would seem to imply that these functions are redundant and that they should be called MOV instead of MOVX. A small note next to these instructions indicates that they move to or from external RAM using an 8-bit address. Where do the other 8-bits come from? The details are found in the introduction to the MOVX instruction. They are reproduced below: The MOVX instructions transfer data between the Accumulator and a byte of external data memory, hence the X appended to MOV. There are two types of instructions differing in whether they provide an eight-bit or sixteen-bit indirect address to external data RAM. In the first type, the contents of R0 or R1 in the current register bank provide an eight-bit address multiplexed with the data on P0. This paragraph is frequently misunderstood as claiming that the 8-bit address MOVX instructions can only access page zero of external RAM. Nothing is further from the truth. The 8031 architecture shares ports with bus lines. When a port is not being used as a bus line, it reverts to the value last output to the port SFR. This means that the high-order address lines (A8-A15) will be outputting the value last stored in the P2 SFR during the aforementioned MOVX instructions! Since the 8031 has only one 16-bit register (DPTR), being able to access external RAM without disturbing its value is extremely useful. Very often one needs to make multiple access to different addresses within a single page. In this case, one can write the page number to P2 and then use R0 or R1 as an offset into the page. This leaves DPTR free for other uses. This is also useful for copying data from one region of external memory to another. If you have ever had to do this, you know how messy it gets: Load the data pointer with the source, fetch, increment the data pointer, store it back, load the data pointer with the destination, store, increment the data pointer, store it back -- for each byte. Instead, set P2 to the source page and R0 to the source offset and use the data pointer for the destination page. Now you can do the following: fetch with the 8-bit MOVX, increment R0, store, increment the data pointer, and repeat 256 times. Then just increment P2 and keep going (R0 will wrap around). One note of warning: Some versions of the 8031 from vendors other than Intel do not completely support this type of access. Test the particular chip version you are planning to use and verify that these instructions operate properly. Some of the 8031 derivatives from Dallas Semiconductor have two data pointers which also help make external RAM access more efficient. In my experience, however, the use of the 8-bit MOVX is generally more efficient than using two data pointers. When dealing with three regions of external data, however, both techniques can be used simultaneously. Return to The 8031 Microcontroller Return to the S. J. Katz Home Page