ELECTRICAL AND COMPUTER ENGINEERING ELEC3270: MICROPROCESSORS
LAB 5: PRINTING TEXT AND STACK MANIPULATION
OBJECTIVE: To print text, analyze the stack, and to manipulate to print text easily SECTIONS:
A. Printing Text to the Terminal Efficiently
B. Examining the Contents of the Stack
C. Passing Variable/Data to a Subroutine through the Stack
D. Printing Text from the Return Address and Changing the Return Address
E. BONUS: Trapping Invalid OpCodes to Print Text
A. PRINTING TEXT TO THE TERMINAL EFFICIENTLY
(20%) (30%) (25%) (25%) (30%)
We have previously seen that we can transmit text to the terminal on the hosting computer. The “OK” subroutine (defined in “end.inc”), used in the base code, loads ACCA with different ASCII values and calls the SendChar subroutine (which utilizes the MCU SCI system to send the data).The “PrtHex2” subroutine also uses the “SendChar” subroutine. In all examples the code individually loaded the ACCA with a value and called this subroutine and repeated this each time for multiple constant values of ACCA (for example, the “OK” that appears when you power up the microcontroller). For this section of the lab you will code a loop (using INDX or INDY) which will read each character of your team member’s names from memory and send them to the terminal followed by a line-feed. You can code your name using the “FCC” (Form table of Constant Characters) as well as “FCB” (Form table of Constant Bytes) for non-ASCII characters (such as line-feed, carriage return or a zero; a zero can specify the end of the text). Once it has printed this text, make it so pressing any key will do it again. The base code, lab5base1.asm, is provided as well as some hints. Save
your file as “SID_5a.asm”.
B. EXAMINING THE CONTENTS OF THE STACK
We have seen that we can place data on and off the stack by using the push and
pull instructions. We can also address the stack indirectly by transferring the
stack pointer (SP) to either the X or Y index register (TSX, TSY) and using any
“,X” or “,Y” index addressing. These op-codes allow us to inspect and possibly
modify the current stack contents (via memory modification) and the pointer
itself (with LDS, TXS and TYS). Download the base code lab5base2.asm and
save it as “SID_5b.asm”. The PRTSTK subroutine needs additional code which prints the contents of the stack from the bottom (the label “STACK” which is set to $29 for this lab) down to, but not including the SP. Your code should print the memory address followed by the contents of that memory. Once you have done this, the output of your program should look like that inset on the upper right. The code initially pushes a $55 and a $AA (both 8 bit) on the stack. We can see this as the $55 is placed at the initial stack address of $0029, and the $AA is placed at the next available address of $0028. Next we push the Condition Code Register (CCR) which is done with the TPA and PSHA instructions (shown as ?? since it may vary).We then place a 16-bit value of $1234 on the stack. This is divided into two 8-bit values and pushed with the low byte first and then the high byte. Lastly we push the contents of the free running timer on the stack (shown here as ?? since it will somewhat random for everyone). The last two values are automatically pushed by the MPU when a JSR or BSR instruction is executed; they are the address (separated into two 8-bit values) of which the subroutine will return to when the RTS instruction executed. We can see that this value is $902E which is the address after the JSR to
our subroutine; we can find this in the LST file (shown inset on the left). Once the code has shown this list, it pauses waiting for a key press. Continually pressing any key will keep pushing the same data on
ELEC3270 Lab #5: Printing Text and Stack Manipulation 1/2
The stack starts with:
36: 902A 36 psha
37: 902B BD 9033 jsr PrtStack 38: 902E BD 90C3 jsr GetChar
the stack (except for the last return address as it was pulled off by the RTS instruction). At some point the SP will go negative (reset back to $FFFF). Remember that the memory from $8000-$FFFF is effectively a ROM and the stack operations cannot write to this memory. The MPU will hang or perform some unexpected set of instructions and eventually reset (you will see “OK” appear in the terminal). We should avoid this in practice, but you can do this here to see what happens.
C. PASSING VARIABLE/DATA TO A SUBROUTINE THROUGH THE STACK
In section A you were asked to write code which would print out your name. One way
you could have done this was to write a subroutine that would print the text that is
located in a particular place in memory. This location would be specified to the
subroutine via a 16-bit register such as the ACCD, INDX, or INDY. This is acceptable if your subroutine only requires a few arguments (like section B), but having more arguments will require a different approach. For this section of the lab, you will rewrite your code from section A to use last 16-bit entry on the stack (after the return PC) to specify the location of where to read the text from. For example, the code (inset on the upper right) calls a subroutine which only accepts one parameter, but you can easily pass more than one piece of information. Once the subroutine returns, it is important to pull off those values so that the stack doesn’t overflow as more subroutines are called later on. Some MPUs have a series of instructions that can easily add to the SP. For example, if we had to pass 20 16-bit variables to a subroutine, we could push those 20 values, call the subroutine, and then pulling them all off the stack. Or we could simply add 20 x 2 to the SP once the subroutine returns; far faster than pulling them all of the stack. This is what is done with languages such as “C” when they are transferred to assembly code. Download the base code lab5base3.asm, modify it appropriately, and save it as “SID_5c.asm”. Remember that the SP points to the next available entry in the stack. The instruction TSX (transfer SP to INDX) actually moves SP+1 to INDX so that INDX will be pointing to the current top most entry in the stack. Once this is done, you can use any INDX addressing to access entries in the stack.
D. PRINTING TEXT FROM THE RETURN ADDRESS AND CHANGING THE RETURN ADDRESS
To maximize the challenge of this lab, we can further extend the work we’ve done in stack interpretation to include some manipulation as well. For this section you will modify your printing subroutine (“PrtRet”) so that it prints the text at the memory location immediately following the BSR or JSR to your subroutine (the first 16- bit value on the stack once you enter your subroutine, the return PC). It will print the text at this location until a zero is found. It will then modify the return PC so that the MPU returns to the point after the zero. Examine the base code provided (lab5base4.asm) as it is written to simply show you the location of where you should start reading from. A guide line is provided to offer some hints. Save your file as “SID_5d.asm”.
E. BONUS: TRAPPING INVALID OPCODES TO PRINT TEXT
The method in section D is quite efficient at coding information for a subroutine as we don’t have to formally provide an address to our data since it follows the call to the subroutine; this requires at most 3 bytes for the JSR. It is however possible to use fewer bytes by using invalid or unused opcodes as it would only require a single byte. When the 68HC11 encounters an invalid opcode, it will call a particular ISR to handle the situation (“trapvect” in our code). In this case the MPU pushes the location of the invalid opcode to the stack rather than the location of the next instruction (like other interrupts). For this section, you will code the trap ISR to read the opcode value to check to see if it is the one you selected (see chapter 7, slide 28). If it isn’t your opcode jump to “resetvect” to simulate a reset, otherwise proceed to printing out the text following that address until zero is encountered. You then need to adjust the return address so it goes back to the address following the zero ASCII terminator. Since this isn’t a timing sensitive interrupt you can issue the “CLI” instruction initially to allow other more interrupts to happen during this ISR. Use the base code provided (lab5base5.asm); it provides some hints. Performing subroutines this way is obviously slower, but it can save a lot of space, save all the callers registers, and allow for user and system code level separation. You can equally do the same using software interrupts (SWI) where, for example, the trailing byte can be using to indicate the operation to be performed. Save your file as “SID_5e.asm”.
ZIP all your ASM files into “SID_5.zip” and upload it to blackboard before the posted due date.
ELEC3270 Lab #5: Printing Text and Stack Manipulation 2/2
本网站支持淘宝 支付宝 微信支付 paypal等等交易。如果不放心可以用淘宝交易！
E-mail: [email protected] 微信:dmxyzl003