Efficient LC3 assembly code to print the numbers leading up to any digit
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I'm using an LC3 microarchitecture simulator to write assembly code. I've only been writing assembly for about three weeks, so I am still very new.
My goal is to print all the numbers leading up to a set value, so for example, if the user selects '6' the console prints 012345. My code works, but the unit test says my code is inefficient or has an infinite loop.
I set the value by manually setting R1
in my simulator to any value. The rest is automated with the code, starting at 0x3000.
LD, R0, X3001 ;Load R0 with 0
0 ;I did this b/c I don't know how to load a register with ascii values
AND R2, R2, #0 ; Set R2=0
NOT R3, R1 ;invert R1, store in R3
ADD R3, R3, #1 ;Add 1 to R3, now R3=-R1
ADD R4, R0, R3 ; better way to perform loop? added these to maintain loop
BRz X300b ; if previous math ever produces 0, skip to halt
OUT ; print single char
ADD R0, R0, #1 ; R0++
ADD R1, R1 #-1 ; R1--
BRnzp X3006 ;Always branch back to the above BR instruction
HALT
Hex:
3000
2000
0030
54a0
967f
16e1
1803
0404
f021
1021
127f
0ffb
f025
So my question is, is there any way to make this more efficient?
assembly lc-3
add a comment |Â
up vote
1
down vote
favorite
I'm using an LC3 microarchitecture simulator to write assembly code. I've only been writing assembly for about three weeks, so I am still very new.
My goal is to print all the numbers leading up to a set value, so for example, if the user selects '6' the console prints 012345. My code works, but the unit test says my code is inefficient or has an infinite loop.
I set the value by manually setting R1
in my simulator to any value. The rest is automated with the code, starting at 0x3000.
LD, R0, X3001 ;Load R0 with 0
0 ;I did this b/c I don't know how to load a register with ascii values
AND R2, R2, #0 ; Set R2=0
NOT R3, R1 ;invert R1, store in R3
ADD R3, R3, #1 ;Add 1 to R3, now R3=-R1
ADD R4, R0, R3 ; better way to perform loop? added these to maintain loop
BRz X300b ; if previous math ever produces 0, skip to halt
OUT ; print single char
ADD R0, R0, #1 ; R0++
ADD R1, R1 #-1 ; R1--
BRnzp X3006 ;Always branch back to the above BR instruction
HALT
Hex:
3000
2000
0030
54a0
967f
16e1
1803
0404
f021
1021
127f
0ffb
f025
So my question is, is there any way to make this more efficient?
assembly lc-3
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm using an LC3 microarchitecture simulator to write assembly code. I've only been writing assembly for about three weeks, so I am still very new.
My goal is to print all the numbers leading up to a set value, so for example, if the user selects '6' the console prints 012345. My code works, but the unit test says my code is inefficient or has an infinite loop.
I set the value by manually setting R1
in my simulator to any value. The rest is automated with the code, starting at 0x3000.
LD, R0, X3001 ;Load R0 with 0
0 ;I did this b/c I don't know how to load a register with ascii values
AND R2, R2, #0 ; Set R2=0
NOT R3, R1 ;invert R1, store in R3
ADD R3, R3, #1 ;Add 1 to R3, now R3=-R1
ADD R4, R0, R3 ; better way to perform loop? added these to maintain loop
BRz X300b ; if previous math ever produces 0, skip to halt
OUT ; print single char
ADD R0, R0, #1 ; R0++
ADD R1, R1 #-1 ; R1--
BRnzp X3006 ;Always branch back to the above BR instruction
HALT
Hex:
3000
2000
0030
54a0
967f
16e1
1803
0404
f021
1021
127f
0ffb
f025
So my question is, is there any way to make this more efficient?
assembly lc-3
I'm using an LC3 microarchitecture simulator to write assembly code. I've only been writing assembly for about three weeks, so I am still very new.
My goal is to print all the numbers leading up to a set value, so for example, if the user selects '6' the console prints 012345. My code works, but the unit test says my code is inefficient or has an infinite loop.
I set the value by manually setting R1
in my simulator to any value. The rest is automated with the code, starting at 0x3000.
LD, R0, X3001 ;Load R0 with 0
0 ;I did this b/c I don't know how to load a register with ascii values
AND R2, R2, #0 ; Set R2=0
NOT R3, R1 ;invert R1, store in R3
ADD R3, R3, #1 ;Add 1 to R3, now R3=-R1
ADD R4, R0, R3 ; better way to perform loop? added these to maintain loop
BRz X300b ; if previous math ever produces 0, skip to halt
OUT ; print single char
ADD R0, R0, #1 ; R0++
ADD R1, R1 #-1 ; R1--
BRnzp X3006 ;Always branch back to the above BR instruction
HALT
Hex:
3000
2000
0030
54a0
967f
16e1
1803
0404
f021
1021
127f
0ffb
f025
So my question is, is there any way to make this more efficient?
assembly lc-3
edited Feb 9 at 13:21
Jamalâ¦
30.1k11114225
30.1k11114225
asked Feb 9 at 5:35
shiftybits
85
85
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
Points about your program.
The 2 instructions at the top don't match the 3 dumped values! There are 12 lines of source but there are 13 values in the dump.
.ORIG X3000
is not an instruction. It's rather a directive and you should not find any value from it in the dump.Why don't you place the data below the
HLT
instruction? A much safer place than within the instructions that get executed. Your trick works because of how theBR
instruction is encoded.On an architecture with limited registers available, it's best to try to use as few as possible to get the work done. Your code uses 5 registers where you can easily do it with 2 registers.
You don't need to use the extra register
R4
to find out if the input was 0. AND-ingR1
to itself will not destroy it and will set the flags for inspecting:AND R1, R1, R1
BRz X300B ;Skip if input was 0It's inefficient to branch always to just another branch instruction. See how I solved the same branching.
An improved version.
My goal is to print all the numbers leading up to a set value
Let's presume the user selects a value from 0 to 9.
For now you've manually set the user's value in R1
. You can use it as a (down)counter. You stop the program as soon as a negative value appears.
.ORIG X3000
LEA R0, X3030 ;Loads "0" in R0[7:0]
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
OUT
only depends on bits [7:0]. The high bits loaded with LEA
don't matter.
If you don't like this trick, then go with the usual way of loading a constant from memory:
.ORIG X3000
LD R0, X3007 ;Loads "0" in R0
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
.FILL X0030 ;Character "0"
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Points about your program.
The 2 instructions at the top don't match the 3 dumped values! There are 12 lines of source but there are 13 values in the dump.
.ORIG X3000
is not an instruction. It's rather a directive and you should not find any value from it in the dump.Why don't you place the data below the
HLT
instruction? A much safer place than within the instructions that get executed. Your trick works because of how theBR
instruction is encoded.On an architecture with limited registers available, it's best to try to use as few as possible to get the work done. Your code uses 5 registers where you can easily do it with 2 registers.
You don't need to use the extra register
R4
to find out if the input was 0. AND-ingR1
to itself will not destroy it and will set the flags for inspecting:AND R1, R1, R1
BRz X300B ;Skip if input was 0It's inefficient to branch always to just another branch instruction. See how I solved the same branching.
An improved version.
My goal is to print all the numbers leading up to a set value
Let's presume the user selects a value from 0 to 9.
For now you've manually set the user's value in R1
. You can use it as a (down)counter. You stop the program as soon as a negative value appears.
.ORIG X3000
LEA R0, X3030 ;Loads "0" in R0[7:0]
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
OUT
only depends on bits [7:0]. The high bits loaded with LEA
don't matter.
If you don't like this trick, then go with the usual way of loading a constant from memory:
.ORIG X3000
LD R0, X3007 ;Loads "0" in R0
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
.FILL X0030 ;Character "0"
add a comment |Â
up vote
1
down vote
accepted
Points about your program.
The 2 instructions at the top don't match the 3 dumped values! There are 12 lines of source but there are 13 values in the dump.
.ORIG X3000
is not an instruction. It's rather a directive and you should not find any value from it in the dump.Why don't you place the data below the
HLT
instruction? A much safer place than within the instructions that get executed. Your trick works because of how theBR
instruction is encoded.On an architecture with limited registers available, it's best to try to use as few as possible to get the work done. Your code uses 5 registers where you can easily do it with 2 registers.
You don't need to use the extra register
R4
to find out if the input was 0. AND-ingR1
to itself will not destroy it and will set the flags for inspecting:AND R1, R1, R1
BRz X300B ;Skip if input was 0It's inefficient to branch always to just another branch instruction. See how I solved the same branching.
An improved version.
My goal is to print all the numbers leading up to a set value
Let's presume the user selects a value from 0 to 9.
For now you've manually set the user's value in R1
. You can use it as a (down)counter. You stop the program as soon as a negative value appears.
.ORIG X3000
LEA R0, X3030 ;Loads "0" in R0[7:0]
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
OUT
only depends on bits [7:0]. The high bits loaded with LEA
don't matter.
If you don't like this trick, then go with the usual way of loading a constant from memory:
.ORIG X3000
LD R0, X3007 ;Loads "0" in R0
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
.FILL X0030 ;Character "0"
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Points about your program.
The 2 instructions at the top don't match the 3 dumped values! There are 12 lines of source but there are 13 values in the dump.
.ORIG X3000
is not an instruction. It's rather a directive and you should not find any value from it in the dump.Why don't you place the data below the
HLT
instruction? A much safer place than within the instructions that get executed. Your trick works because of how theBR
instruction is encoded.On an architecture with limited registers available, it's best to try to use as few as possible to get the work done. Your code uses 5 registers where you can easily do it with 2 registers.
You don't need to use the extra register
R4
to find out if the input was 0. AND-ingR1
to itself will not destroy it and will set the flags for inspecting:AND R1, R1, R1
BRz X300B ;Skip if input was 0It's inefficient to branch always to just another branch instruction. See how I solved the same branching.
An improved version.
My goal is to print all the numbers leading up to a set value
Let's presume the user selects a value from 0 to 9.
For now you've manually set the user's value in R1
. You can use it as a (down)counter. You stop the program as soon as a negative value appears.
.ORIG X3000
LEA R0, X3030 ;Loads "0" in R0[7:0]
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
OUT
only depends on bits [7:0]. The high bits loaded with LEA
don't matter.
If you don't like this trick, then go with the usual way of loading a constant from memory:
.ORIG X3000
LD R0, X3007 ;Loads "0" in R0
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
.FILL X0030 ;Character "0"
Points about your program.
The 2 instructions at the top don't match the 3 dumped values! There are 12 lines of source but there are 13 values in the dump.
.ORIG X3000
is not an instruction. It's rather a directive and you should not find any value from it in the dump.Why don't you place the data below the
HLT
instruction? A much safer place than within the instructions that get executed. Your trick works because of how theBR
instruction is encoded.On an architecture with limited registers available, it's best to try to use as few as possible to get the work done. Your code uses 5 registers where you can easily do it with 2 registers.
You don't need to use the extra register
R4
to find out if the input was 0. AND-ingR1
to itself will not destroy it and will set the flags for inspecting:AND R1, R1, R1
BRz X300B ;Skip if input was 0It's inefficient to branch always to just another branch instruction. See how I solved the same branching.
An improved version.
My goal is to print all the numbers leading up to a set value
Let's presume the user selects a value from 0 to 9.
For now you've manually set the user's value in R1
. You can use it as a (down)counter. You stop the program as soon as a negative value appears.
.ORIG X3000
LEA R0, X3030 ;Loads "0" in R0[7:0]
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
OUT
only depends on bits [7:0]. The high bits loaded with LEA
don't matter.
If you don't like this trick, then go with the usual way of loading a constant from memory:
.ORIG X3000
LD R0, X3007 ;Loads "0" in R0
BRnzp X3004 ;Go test for 0 input
OUT ;Display R0[7:0]
ADD R0, R0, #1 ;R0++
ADD R1, R1, #-1 ;R1--
BRzp X3002 ;Continue with zero or positive
HLT ;Stop (R1 = #-1)
.FILL X0030 ;Character "0"
edited Feb 15 at 11:55
answered Feb 14 at 16:34
Fifoernik
27827
27827
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187152%2fefficient-lc3-assembly-code-to-print-the-numbers-leading-up-to-any-digit%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password