Sei sulla pagina 1di 4

I know that most people wish that LC-3 had a few extra commands.

Subtraction, multiplication, ifelse blocks, for loops . . . the list of features goes on and on. I personally cannot believe some of the features that LC-3 lacks. Some of these feaures arent even a problem with the language; for example, the fact that every label is a global label is a weakness of the LC-3 preproccessor (or lack thereof) . For example, if I wanted to copy and paste a routine to use in another program, I'm gonna have to check that I dont use variables or labels that are used anywhere else in my program. This becomes a problems especially when I have to write if-then-else blocks, or when I have very common variable names, like ASCII_ZERO. "Grownup" assemblers often solve this problem by introducing local labels: labels that are "local" to the last non-local label. For example, if I have the code Code:

MY_FUNC: ... ret and want to add in a while loop, most assemblers will allow me to declare the while loop label like this: Code:

MY_FUNC: .WHILE: ... ret Notice the dot? this means that the while loop is local to the function. If I code in a jump to that while loop, like this Code:

jump .WHILE then it will jump to the local while label, not some other while label located somewhere else. This feature, along with being able to use characters in a .fill, I feel should be standard for LC-3. I am currently working on a preproccessor for LC-3 that will convert LC-3 code with the added functionality to standard LC-3 code. Examples what I am currently able to do follow: LC-3 with added functionality: Code:

.orig x3000 MAINZOR: ld r1, .NUM1 ld r2, .NUM2 jsr DIVIDE_R1_BY_R2 ld r4, .ASCII_ZERO add r0, r3, r4 out halt .NUM1 .fill #18 .NUM2 .fill #6 .ASCII_ZERO .fill '0' DIVIDE_R1_BY_R2: ;divides r1 by r2 and returns in r3 zero r3 ;r1 is accumulator .loop: ;loop to divide sub r1, r1, r2 ;subtract away! add r3, r3, #1 test r1 BRp .loop add r3, r3, #-1 ret .NUM1 .fill #4 .NUM2 .fill #8

NEW_FUNC: if r3 then if r2 then add r1, r1, #1 else add r3, r3, #1 end else add r2, r2, #1 end if r5 then add r5, r5, #1 end ret Gets converted to: Code:

.orig x3000 MAINZOR: ld r1, MAINZOR_NUM1 ld r2, MAINZOR_NUM2 jsr DIVIDE_R1_BY_R2 ld r4, MAINZOR_ASCII_ZERO add r0, r3, r4 out halt MAINZOR_NUM1 .fill #18 MAINZOR_NUM2 .fill #6 MAINZOR_ASCII_ZERO .fill #48 ;'0' DIVIDE_R1_BY_R2: ;divides r1 by r2 and returns in r3 and r3, r3, #0 ;r1 is accumulator DIVIDE_R1_BY_R2_loop: ;loop to divide not r2, r2 ;negate r2 add r2, r2, #1 add r1, r1, r2 ;subtract away! not r2, r2 ;negate r2 add r2, r2, #1 add r3, r3, #1 and r1, r1, #-1 BRp DIVIDE_R1_BY_R2_loop add r3, r3, #-1 ret DIVIDE_R1_BY_R2_NUM1 .fill #4 DIVIDE_R1_BY_R2_NUM2 .fill #8 NEW_FUNC: and r3, r3, #-1 BRz NEW_FUNC_ellse0 and r2, r2, #-1 BRz NEW_FUNC_ellse1 add r1, r1, #1 BRnzp NEW_FUNC_end1 NEW_FUNC_ellse1: ;else: add r3, r3, #1 NEW_FUNC_end1: BRnzp NEW_FUNC_end0 NEW_FUNC_ellse0: ;else: add r2, r2, #1 NEW_FUNC_end0: and r5, r5, #-1 BRz NEW_FUNC_end2 add r5, r5, #1 NEW_FUNC_end2:

ret Pretty cool, huh? Hopefully I will have a working version uploaded soon.

LC3-1 ONLINE EXAMPLE #1 (10/08/2003 and 10/10/2003) (used in lecture 18 to introduce the LC-3 instructions, plus assembler directives, plus concepts such as the translation process... from idea to running program) (used in lecture 19 to answer questions about specific assembler directives, and to count the number of memory words required to store this program) Translate the HLL example#1 into LC-3 Code, and turn it into a complete program. LC-3 Reference to use for this program: ---------------------------------------------------------------INSTRUCTIONS -------------------------------ADD Rd, Rs1, Rs2 Rd <= Rs1 + Rs2 ADD Rd, Rs1, <immediate constant> Rd <= Rs1 + SExt(immediate constant) AND Rd, Rs1, Rs2 Rd <= Bitwise and of Rs1 and Rs2 AND Rd, Rs1, <immediate constant> Rd <= Bitwise and of Rs1 and SExt(cons) NOT Rd, Rs1 Rd <= Bitwise logical negation of R1 BR<cc> SYMBOLIC_LABEL if <cc is true> PC <= effective addr of SYMBOLIC_LABEL LD Rd, SYMBOLIC_LABEL Rd <= MEM[eff. addr. of SYMBOLIC_LABEL] ST Rs, SYMBOLIC_LABEL MEM[eff. addr. of SYMBOLIC_LABEL] <= Rs TRAP <immediate constant of 8 bits> "Call the OS function named by the immediate constant" <immediate constant> is sign extended to 16bits and can be specified in 4 ways: <value> default base is decimal. #<value> indicates value digits are in base 10 x<value> indicates value digits are in base 16 b<value> indicates value digits are in base 2 -------------------------------PSEUDO INSTRUCTIONS PUTS is a pseudo instruction for TRAP x22 HALT is a pseudo instruction for TRAP x25 -------------------------------ASSEMBLER DIRECTIVES 1) The .ORIG causes the assembler to specify in the object file that the loader must start loading the executable file at the specified address (this includes loading both machine language instructions and initialized memory locations) .ORIG <start_loading address> 2) The .BLKW is an assembler directive that reserves (i.e. allocates) the required memory space for a variable. (will involve the loader) .BLKW <number of words to be reserved/allocated> 3) The .FILL assembler directive reserves and initializes 1 memory location. .FILL <value to be filled into 1 word of memory> 4) Similarly to the .FILL, the .STRINGZ assembler directive reserves and initializes N+1 memory locations. The N+1 memory location is set to zero (as a sentinel value). .STRINGZ "<a sequence of N characters>" 5) The assembler stops assembling once it encounters an .END .END

------------------------------------------------------------------------LC-3 Example #1: HLL: { int A=100; int B=-200; int C; ...<omitted for brevity> if (A-B) C=0; else C=2; ...<omitted for brevity> System.out.println ("ALL DONE") } LC-3 CODE .ORIG x3000 MAIN LD R1, A LD R2, B ; code omitted for brevity IFO1 NOT R0, R2 ; Calculate (-B) ADD R0, R0, #1 ADD R0, R1, R0 ; A + (-B) BRnp ELSE01 ; branch if A-B != 0 (opposite of the HLL if)

THEN01 AND R3, R3, #0 ; C = 0 ST R3, C BR ENDIF01 ELSE01 AND R3, R3, #0 ; C = 2 ADD R3, R3, #2 ; obviously a compiler could optimize the then ST R3, C ; and else code to avoid duplication ENDIF01 LEA R0, ENDMSG ; printout "ALL DONE" PUTS HALT A .FILL 100 ; allocates 1 memory location, and inits it to 100 B .FILL -200 ; allocates 1 memory location,and inits it to -200 C .BLKW 1 ; allocates 1 memory location only ENDMSG .STRINGZ "ALL DONE" ; allocates 9 memory locations and inits them ; to x0041, x004c, x004c, x0020, ; x0044, x004f, x004e, x0045, x0000 .END -----------------------------------------------------------------------The Assembler Symbol Table (after pass1) will contain: SYMBOLIC NAME ADDRESS ------------- ------MAIN x3000 IF01 x3002 THEN01 x3006 ELSE01 x3009 ENDIF01 x300c A x300f B x3010 C x3011 ENDMSG x3012 (note, the E will be stored in address x3019 and the sentinel is stored in address x301a) -----------------------------------------------------------------------TOTAL amount of memory required for this program and data: 27 memory locations starting at address x3000 thru x301a memory location 0x300f will contain 0x0064 memory location 0x3012 will contain 0x0041

Potrebbero piacerti anche