Lab 2 Input and Output Lab 2 Use Traps Write (i.e. design and implement) an assembly language program that will accept user input from the keyboard and echo this to the terminal screen. Input should terminate when the user presses the '.' key. The code should also convert all lower case letters to upper case. : User types: Code displays: abcde1234uiop. ABCDE1234UIOP. Trap #1 (ed Read) Waits for a character to be sent down the serial line. (Typically a keypress from the console window). The ascii value of the character read is returned in d0 Trap #2 (ed Write) Waits for free space in the internal transmit buffer and then sends the character held in d0 30 th Lecture, Dr. Michael Manzke, Page: 1 30 th Lecture, Dr. Michael Manzke, Page: 2 Lab 2 English Lab 2 Pseudocode Until the user inputs the '.' key read a character from the terminal using trap #1. Check to see if this is a lower case letter (i.e. in the range 'a' - 'z'). If it is then subtract 'a'-'a' from the ascii value to convert it to upper case. Write the ascii value back to the terminal using trap #2. Note that we must read at least 1 character from the user before processing. Therefore it is more appropriate to use a do-while loop rather than a while-do loop. 30 th Lecture, Dr. Michael Manzke, Page: 3 do { ascii = Read(); if(ascii >= 'a' AND ascii <= 'z') { ascii=ascii-'a'+'a'; } Write(ascii) } while(ascii!= '.') 30 th Lecture, Dr. Michael Manzke, Page: 4 1
Lab 2 Assembly Language s Echo user input to the terminal converting all chars to uppercase and terminating on '.' org $1000 DO trap #1 ascii=read() cmp.b #$60,d0 if lowercase bls ENDIF cmp.b #'z',d0 bhi ENDIF sub.b #'a',d0 convert to add.b #'A',d0 UPPER case ENDIF trap #2 cmp.b #'.',d0 while ascii!='.' bne DO trap #0 30 th Lecture, Dr. Michael Manzke, Page: 5 If a lot of data is being transferred from the calling program to the subroutine. Entire blocks of memory are set aside and designated as parameter blocks. May be located anywhere in memory. Only the address of the start of the block is passed to the subroutine Individual parameter in the block may be accessed using d(an) addressing mode: 30 th Lecture, Dr. Michael Manzke, Page: 6 s PB-Pointer Memory 1 2 3 4 Calculate the 2s Complement of a 64-bit No. TC64(Num) Num (a0) Variable MASK equ $ffffffff TC64 eori.l #MASK,4(a0) Invert Low Long eori.l #MASK,(a0) Invert High Long addi.l #1,4(a0) Add 1 to Low IF bcc ENDIF IF(Carry) THEN addi.l #1,(a0) Add 1 to High ENDIF rts ENDIF In the above example a parameter block was used to represent the 64-bit number number (i.e.: 2long words). The a0 register is assumed to contain the address of the start of the parameter block. 30 th Lecture, Dr. Michael Manzke, Page: 7 30 th Lecture, Dr. Michael Manzke, Page: 8 2
On the Use a technique similar to parameter blocks In this case the block is located on the stack This technique is used widely by compilers to implement parameter passing required by high level languages. Difficulties: The return address and other values pushed onto the stack have to be taken into Remember: The PC has also been pushed onto the stack when the jsr/bsr has been executed. To facilitate this method the 68332 instructions link/unlk Re-write the FILL subroutine so that the parameters are passed via a stack parameter block (without using link/unlink). 30 th Lecture, Dr. Michael Manzke, Page: 9 30 th Lecture, Dr. Michael Manzke, Page: 10 Fill Memory Subroutine (start) Fill Memory Subroutine (end) The Fill Memory subroutine FILL(Prt,,) 10(a7) value 6(a7) value 4(a7) value FILL move.l a6,-(a7) Save(a6) movea.l a7,a6 =+4; adda.l #4,a6 movem.l a0/d0-d1/d7,-(a7) Save(Regs) Copy the parameters off the stack into regs. move.w 4(a6),d1 Get move.l 6(a6),d0 Get move.l 10(a6),a0 Get Fill the memory clr.l d7 Count=0; WHILE cmp.l d7,d0 WHILE Count<= beq.s ENDWHILE DO move.b d1,(a0)+ ()+=; addi.l #1,d7 ++; bra WHILE ENDWHILE Restore all the registers ENDWHILE movem.l (a7)+,a0/d0-d1/d7 movea.l (a7)+,a6 rts 30 th Lecture, Dr. Michael Manzke, Page: 11 30 th Lecture, Dr. Michael Manzke, Page: 12 3
Call Fill Subroutine What happens on the stack? To call the new FILL subroutine, the parameter must be loaded into the parameter block on the stack: Program to demonstrate passing parameters on the stack. Pushes parms to FILL and then calls it. Pops parms on return. org $4000 move.l #$4600,-(a7) Push(.l) move.l #30,-(a7) Push(.l) move.w #'A',-(a7) Push(.w) jsr FILL FILL($4600,30,'A') adda.l #10,a7 POP the parms trap #0 This seemingly overly complicated procedure is to allow us to use the stack as normal (ie: for saving values of registers in the subroutine) and yet still accessing the stack as a parameter block. 30 th Lecture, Dr. Michael Manzke, Page: 13 The following series shows what happens on the stack during a call to the FILL subroutine: Before FILL is called Bottom Top of of After FILL is called Bottom Top of of 30 th Lecture, Dr. Michael Manzke, Page: 14 What happens on the stack? During the execution of the FILL subroutine, the a6 register is used as a temporary pointer to the parameter block on the stack, so that the may be used as normal to save register on the stack etc.: FILL: Use a6 as param. block pointer Bottom Top of Saved old a6 a6 FILL: Save registers as normal Bottom Top of of Saved old a6 Saved Registers a6 After execution of the while loop The FILL subroutine Restores the register Restores a6 And returns as normal Which removes the return address from the stack The calling program must remove the parameter block from the stack By adding 10 to the The parameter block is 10 bytes long 30 th Lecture, Dr. Michael Manzke, Page: 15 30 th Lecture, Dr. Michael Manzke, Page: 16 4
Frames The link and unlk are used to manage the stack in this way. They are used to create stack frames. Reserved space for parameter on the stack frames are usually used to contain local variable in subroutines. move.l d0,-(a7) move.w d1,-(a7) bsr Routine adda.l #6,a7 Pop params Before Routine is called After bsr Bottom Top of of Bottom Top of of 30 th Lecture, Dr. Michael Manzke, Page: 17 30 th Lecture, Dr. Michael Manzke, Page: 18 link & unlk Frame Pointer Routine link a0,#-8 2 local longs move.l d0,-4(a0) 1 st local move.l d7,-8(a0) 2 nd local COMP... unlk a0 remove frame rts a0 After link Bottom Top of of Old a0 a0 Executing main Bottom Top of Old a0 saved d0 saved d7 Frame 30 th Lecture, Dr. Michael Manzke, Page: 19 A0 is known as the frame pointer. All local variables and parameter are accessed via it. Local variable -> Negative offset -> Positive offset 30 th Lecture, Dr. Michael Manzke, Page: 20 5