![]() |
Jupyter at Bryn Mawr College |
|
|
Public notebooks: /services/public/dblank / CS240 Computer Organization / 2017-Fall / Notebooks |
Figure 7.2: The assembly language program to count occurrences of a character.
;
; Program to count occurrences of a character in a File.
; Character to be input from the keyboard.
; Result to be displayed on the monitor.
; Program works only if no more than 9 occurrences are found.
;
;
; Initialization
;
.ORIG x3000
AND R2,R2,#0 ; R2 is counter, initialize to 0
LD R3,PTR ; R3 is pointer to characters
TRAP x23 ; R0 gets character input
LDR R1,R3,#0 ; R1 gets the next character
;
; Test character for end of file
;
TEST ADD R4,R1,#-4 ; Test for EOT
BRz OUTPUT ; If done, prepare the output
;
; Test character for match. If a match, increment count.
;
NOT R1,R1
ADD R1,R1,R0 ; If match, R1 = xFFFF
NOT R1,R1 ; If match, R1 = x0000
BRnp GETCHAR ; If no match, do not increment
ADD R2,R2,#1
;
; Get next character from the file
;
GETCHAR ADD R3,R3,#1 ; Increment the pointer
LDR R1,R3,#0 ; R1 gets the next character to test
BRnzp TEST
;
; Output the count.
;
OUTPUT LD R0,ASCII ; Load the ASCII template
ADD R0,R0,R2 ; Convert binary to ASCII
OUT ; ASCII code in R0 is displayed
;; Show a linefeed number to advance line:
AND R0,R0, #0
ADD R0,R0, #10
TRAP x21 ; ASCII code in R0 is displayed
TRAP x25 ; Halt machine
;
; Storage for pointer and ASCII template
;
ASCII .FILL x0030
PTR: .FILL FILE
FILE .STRINGZ "xxxxxxxxxxxxxxxxxxxxxxxxxxyz"
.FILL #4
.END
%dis
%exe
Symbol | Address |
---|---|
TEST | x3004 |
GETCHAR | x300B |
OUTPUT | x300E |
ASCII | x3015 |
PTR | x3016 |
FILE | x3017 |
Consider:
LD R3,PTR ; R3 is pointer to characters
PTR is x3016. We know that PC+ (x3002) plus offset should equal x3016, so we simply subtract: x3016 - x3002 to get x0014. Is this what the %dis shows?
x3001: x2614 - 0010 0110 0001 0100 - 0010 011 0 0001 0100
LD R3 x14
LD R3 #20
High-level | LC3 |
---|---|
int a; // simple variable (uninitialized) | a .BLKW 1 ; simple variable (or .FILL 0) |
int b = 2014; // simple initialized variable | b .FILL #2014 ; simple initialized variable |
int c[10]; // array of 10 (uninitialized) | c .BLKW 10 ; array of ten ints (initialized to 0) |
int *d = &e; // address of e | d .FILL e ; store address of e in variable d |
High-level | LC3 |
---|---|
b = a; | LD R0, a ; load from memory to a register |
ST R0, b ; store from register to memory | |
b = a + 1; | LD R0, a ; load from memory to a register |
ADD R0, R0, #1 ; increment value | |
ST R0, b ; store from register to memory |
High-level | LC3 |
---|---|
pa = &a; | LEA R0, a ; get the address of the variable |
ST R0, pa ; store it in the pointer variable | |
b = *pa; | LDI R0, pa ; get the value at the address stored in pa |
ST R0, b ; store it in b | |
*pa = b; | LD R0, b ; load the value of b |
STI R0, pa ; store it at the address stored in pa |
High-level | LC3 |
---|---|
if (a < b) { | LD R0, a ; load a |
LD R1, b ; load b | |
NOT R1, R1 ; begin 2's complement of b | |
ADD R1, R1, #1 ; R1 now has -b | |
ADD R0, R0, R1 ; R0 = a + (-b) | |
; condition code now set | |
BRzp SKIP ; if false, skip over code | |
// do something | ; code to do something (the then clause) |
} | SKIP ; remainder of code after if |
High-level
uint a = 1;
uint b = 2;
if (a < b) {
// do something
}
else {
// do something else
}
LC-3
LD R0, A ; load a
LD R1, B ; load b
NOT R1, R1 ; begin 2's complement of b
ADD R1, R1, #1 ; R1 now has -b
ADD R0, R0, R1 ; R0 = a + (-b)
; condition code now set
BRzp ELSE ; if false, skip over code
; do something
BR END_ELSE ; don't execute else code
ELSE: ; code for else clause here
; do something else
END_ELSE: ; remainder of code after else
HALT
A: .FILL x01
B: .FILL x02
.ORIG x4000
;;JSR START
;;HALT
LEA R0, START
JSRR R0
HALT
START ST R7,SaveR7
JSR SaveReg
;;
;; do lots of stuff that messes with all of the resgisters!!
;;
JSR RestoreReg
LD R7,SaveR7
RET ; JMP R7 terminates
SaveR7 .FILL x0000 ;; close to where it is used
SaveReg ST R1,SaveR1
ST R2,SaveR2
ST R3,SaveR3
ST R4,SaveR4
ST R5,SaveR5
ST R6,SaveR6
RET
;
RestoreReg LD R1,SaveR1
LD R2,SaveR2
LD R3,SaveR3
LD R4,SaveR4
LD R5,SaveR5
LD R6,SaveR6
RET
SaveR1 .FILL x0000
SaveR2 .FILL x0000
SaveR3 .FILL x0000
SaveR4 .FILL x0000
SaveR5 .FILL x0000
SaveR6 .FILL x0000
.END
%exe