I can't find out why the loop isn't stopping-LC3 - lc3

I'm just a super newbie like I just learn how to do this just for 12 hrs I was wondering why my loop is not stopping. Can you help me find what is wrong. I know this code is garbage, please bear with me.
So our task is to ask the user to ask the user input a string with max 80 characters and should end with period since it is our basis to know if it is the end of the string. The program will count the characters and words and display it, but in my case the program doesn't stop. Please help.
.ORIG X3000
LEA R0, PROMPT_ENTER ;Message for entering number.
PUTS
LEA R2, SENTENCE ;allocated memory
AND R3, R3, #0 ;setting R3 to zero for word counter.
ADD R3, R3, #1
AND R1, R1, #0 ;setting R4 to zero for char counter.
;---------ASKING USER TO INPUT A SENTENCE------
GET_USER_INPUT: ;loop for getting characters.
GETC
OUT
STR R0, R2, #0 ;r0 -> ( memory address stored in r2 + 0 )
PUT
ADD R2, R2, #1 ;increments the memory pointer
ADD R0, R0, #-10 ;decrements loop to proceed when pressed enter.
BRz COUNT_LENGTH
BRnp GET_USER_INPUT
;--------Element counter----
COUNT_LENGTH:
AND R0, R0, #0
LEA R4, SENTENCE
LDR R0, R4, #0
ADD R0, R0, #-10
BRz EMPTY
BRnp COUNT_ELEMENTS
EMPTY:
AND R0, R0, #0
LEA R0, PROMPT_NULL
PUTS
HALT
COUNT_ELEMENTS:
AND R0, R0, #0
LEA R4, SENTENCE
LDR R0, R4, #0
LD R6, TMNT
ADD R0, R0, R6
BRz END_OF_SENTENCE
LDR R0, R4, #0
LD R6, SPACE
ADD R0, R0, R6
BRz WORD_COUNT
ADD R4, R4, #1
ADD R1, R1, #1
BRnp COUNT_ELEMENTS
WORD_COUNT:
ADD R4, R4, #1
ADD R3, R3, #1
JSR COUNT_ELEMENTS
END_OF_SENTENCE:
AND R0, R0, #0
LDR R3, R3, #0
LD R5, ASCII
ADD R0, R0, R5
OUT
AND R0, R0, #0
LDR R1, R1, #0
ADD R0, R0, R1
OUT
HALT
SENTENCE .BLKW #80 ;initialize the array named sentence with length 80
TMNT .fill #-89
SPACE .fill #-32
ASCII .fill #48
;----MESSAGES------
PROMPT_ENTER .stringz "Enter the word(maximum 80 characters): \n"
PROMPT_AGAIN .stringz "Do you want to try again? Y/N: \n"
PROMPT_NULL .stringz "Error: Please enter a sentence!"
PROMPT_NOTMNT .stringz "Error: No terminating symbol (.) is expected at the end!"
PROMPT_DSPACE .stringz "Error: Multiple white space is not allowed!"
.END

I've only skimmed though this code.
it is an infinite loop because you reset R4 to point to the start of SENTENCE in each iteration of COUNT_ELEMENTS.
I can see in your code where you are incrementing R4 before going back to COUNT_ELEMENTS (btw JSR is only used to call a subroutine if you want to Branch unconditionally use BR).
You'd want to set R4 to point to SENTENCE only once. I do believe you can simply remove the LEA R4, SENTENCE within COUNT_ELEMENTS since it was set previously as part of COUNT_LENGTH.
In the future I would recommend pulling your code up in a lc3 simulator and stepping through it examining the values of the registers as you step though.

Related

Why does _exit() jump to _etext?

I am running a project using the ARM Embedded Tollchain on a stm32 microcontroller which uses the newLib.
I called assert(false) to test the assert output and ended in a Hard Fault Exception. I debugged into the assembly of assert(...) and found out that a subsequent call to _exit(1) jumps to a Address which is called _etext. Taking a look to the manpage of _etext shows that _etext is the address of the end of the .text section.
I am really confused. Normally I had supposed that _exit() is calling __exit() (which is defined as global symbol by the newLib) which I had implemented in a file named syscalls.c.
Why does _exit() jump to _etext?
Here are some cope snippets for a better understanding:
The subsequent call to _exit() by assert() taken from newLib 2.5:
_VOID
_DEFUN_VOID (abort)
{
#ifdef ABORT_MESSAGE
write (2, "Abort called\n", sizeof ("Abort called\n")-1);
#endif
while (1)
{
raise (SIGABRT);
_exit (1);
}
}
The disassembly of abort and assert. Take a special look to address 0808a10a where the jump to 80a5198 (_etext) is performed:
abort:
0808a100: push {r3, lr}
0808a102: movs r0, #6
0808a104: bl 0x808bfdc <raise>
0808a108: movs r0, #1
0808a10a: bl 0x80a51d8
0808a10e: nop
__assert_func:
0808a110: push {lr}
0808a112: ldr r4, [pc, #40] ; (0x808a13c <__assert_func+44>)
0808a114: ldr r6, [r4, #0]
0808a116: mov r5, r0
0808a118: sub sp, #20
0808a11a: mov r4, r3
0808a11c: ldr r0, [r6, #12]
0808a11e: cbz r2, 0x808a136 <__assert_func+38>
0808a120: ldr r3, [pc, #28] ; (0x808a140 <__assert_func+48>)
0808a122: str r2, [sp, #8]
0808a124: stmia.w sp, {r1, r3}
0808a128: mov r2, r4
0808a12a: mov r3, r5
0808a12c: ldr r1, [pc, #20] ; (0x808a144 <__assert_func+52>)
0808a12e: bl 0x808a5f4 <fiprintf>
0808a132: bl 0x808a100 <abort>
0808a136: ldr r3, [pc, #16] ; (0x808a148 <__assert_func+56>)
0808a138: mov r2, r3
0808a13a: b.n 0x808a122 <__assert_func+18>
0808a13c: str r0, [r3, #120] ; 0x78
0808a13e: movs r0, #0
0808a140: add r12, r11
0808a142: lsrs r2, r1, #32
0808a144: add r12, sp
0808a146: lsrs r2, r1, #32
0808a148: add r8, sp
0808a14a: lsrs r2, r1, #32
The lss-file which shows that 80a5198 is the address of _etext:
0808a0c0 <abort>:
808a0c0: b508 push {r3, lr}
808a0c2: 2006 movs r0, #6
808a0c4: f001 ff6a bl 808bf9c <raise>
808a0c8: 2001 movs r0, #1
808a0ca: f01b f865 bl 80a5198 <_etext>
808a0ce: bf00 nop

How to align to cache line GCC ldr pc-relative

In ARM, GCC uses the PC-relative load is usually used to load constants into registers. The idea is that you store the constant relative to the instruction loading the constant. E.g. the following instruction can be used to load a constant from the address PC+8+offset
ldr r0, [pc, #offset]
As result, the .text segment interleaves instructions and data. The latter usually stored at the end of function's code. E.g.
00010860 <call_weak_fn>:
10860: e59f3014 ldr r3, [pc, #20] ; 1087c <call_weak_fn+0x1c>
10864: e59f2014 ldr r2, [pc, #20] ; 10880 <call_weak_fn+0x20>
10868: e08f3003 add r3, pc, r3
1086c: e7932002 ldr r2, [r3, r2]
10870: e3520000 cmp r2, #0
10874: 012fff1e bxeq lr
10878: e1a00000 nop ; (mov r0, r0)
1087c: 00089790 muleq r8, r0, r7
10880: 00000074 andeq r0, r0, r4, ror r0
For a research project, I would like to ensure that code and constant never reside on the same cache line (i.e. block 64 bytes aligned).
Is it possible to align the constants generated by GCC?

"Access to unaligned memory location, bad address=ffffff"

I'm trying to read integers from an input.txt file, below is my read loop where I'm attempting to read and store the integers into an array. I keep getting "Access to unaligned memory location, bad address=ffffff" on any line after the line with "LDR R2, [R2,R5,LSL #2]...im using ARM SIM. Does anyone know what I'm doing wrong?
start:
MOV R5, #0 #int i
MOV R1, #0
swi SWI_Open
LDR R1,=InFileH
STR R0,[R1]
MOV R3, #0
readloop:
LDR R0, =InFileH
LDR R0, [R0]
swi SWI_RdInt
CMP R0, #0
BEQ readdone
#the int is now in R0
MOV R1, R0
LDR R3,=a
STR R2,[R3,R5,LSR#2]
MOV R2, R1
ADD R5, R5, #1 #i++
bal readloop
readdone:
MOV R0, #0
swi SWI_Close
swi SWI_Exit
.data
.align 4
InFileH: .skip 4
InFile: .asciz "numbers.txt"
OutFile: .asciz "numsort.txt"
OutFileH: .skip 4
NewLine: .asciz "\n"
a: .skip 400
i had faced similar issue while programming arm assembly
this was because it was expecting offset in multiples of 4
STR R2, [R1, #2]
the above instruction throws the similar error. so it was resolved by using
STR R2, [R1, #4]
for better understanding clickhere

LC3 continue getting a trap was executed with an illegal vector number

I am trying to create a program that will present the number input in binary to the user. Currently, all I have is the setup to get the user's number once they are finished typing all of their characters, however I don't understand why the code below will not run.
.ORIG x3000
RESET
AND R1, R1, #0
AND R2, R2, #0
AND R3, R3, #0
AND R4, R4, #0
ASCII .FILL #-48 ;ASCII CONVERSION
LD R5, ASCII ;
AND R6, R6, #0 ;NEGATIVE FLAG
DISPLAY .STRINGZ "\nTYPE A NUMBER THEN PRESS ENTER: "
LEA R0 DISPLAY
PUTS
loop
LOOP
GETC
OUT
AND R4, R4, #0 ;CHECK IF LF
ADD R4, R4, #-10 ;
ADD R4, R4, R0 ;
BRZ READY
LD R4, CHECKN ;check if negative
AND R4, R4, #0 ;
ADD R4, R4, R0 ;
BRZ NEGATIVE ;
ADD R1, R0, R5
BRNZP MULTIPLY
ADD R2, R1, R3
BRNZP LOOP
NEGATIVE
ADD R6, R6, #1
BRNZP LOOP
multiply by adding the same number 10 times
MULTIPLY
ADD R3, R2, R2
ADD R3, R3, R2
ADD R3, R3, R2
ADD R3, R3, R2
ADD R3, R3, R2
ADD R3, R3, R2
ADD R3, R3, R2
ADD R3, R3, R2
ADD R3, R3, R2
BRNZP LOOP
CHECKN .FILL #-45
READY
HALT
.END

LC3 trap executed illegal vector number

I'm trying to count the number of characters in LC3 simulator and keep getting "a trap was executed with an illegal vector number".
These are the objects I execute
charcount.obj:
0011000000000000
0101010010100000
0010011000010000
1111000000100011
0110001011000000
0001100001111100
0000010000001000
1001001001111111
0001001001100001
0001001001000000
0000101000000001
0001010010100001
0001011011100001
0110001011000000
0000111111110110
0010000000000100
0001000000000010
1111000000100001
1111000000100101
1110001011111111
0000000000110000
and verse:
.ORIG x3100
.STRINGZ "Simple Simon met a pieman,"
.STRINGZ "Going to the fair;"
.STRINGZ "Says Simple Simon to the pieman,"
.STRINGZ "Let me taste your ware."
.FILL x04
.END
Looks like we're going to need more information before we can help you much. I understand you've provided us with some binary and I ran that through the LC3 simulator. Here's where I'm a bit lost, which string would you like to count and where is it stored?
After trying to piece together what you've provided here's what I've found.
Registers:
R0 x0061 97
R1 x0000 0
R2 x0000 0
R3 xE2FF -7425
R4 x0000 0
R5 x0000 0
R6 x0000 0
R7 x3003 12291
PC x3004 12292
IR x62C0 25280
CC Z
Memory:
x3000 0101010010100000 x54A0 AND R2, R2, #0
x3001 0010011000010000 x2610 LD R3, x3012
x3002 1111000000100011 xF023 TRAP IN
x3003 0110001011000000 x62C0 LDR R1, R3, #0
x3004 0001100001111100 x187C ADD R4, R1, #-4
x3005 0000010000001000 x0408 BRZ x300E
x3006 1001001001111111 x927F NOT R1, R1
x3007 0001001001100001 x1261 ADD R1, R1, #1
x3008 0001001001000000 x1240 ADD R1, R1, R0
x3009 0000101000000001 x0A01 BRNP x300B
x300A 0001010010100001 x14A1 ADD R2, R2, #1
x300B 0001011011100001 x16E1 ADD R3, R3, #1
x300C 0110001011000000 x62C0 LDR R1, R3, #0
x300D 0000111111110110 x0FF6 BRNZP x3004
x300E 0010000000000100 x2004 LD R0, x3013
x300F 0001000000000010 x1002 ADD R0, R0, R2
x3010 1111000000100001 xF021 TRAP OUT
x3011 1111000000100101 xF025 TRAP HALT
x3012 1110001011111111 xE2FF LEA R1, x3112
x3013 0000000000110000 x0030 NOP
The values displayed in the registers is what I get when I stop after line x3003. For some reason the literal value of xE2FF gets loaded into register R3. After that the value of 0 at memory location xE2FF is loaded into register R1 and then the problems mount from there.
I would recommend displaying your asm code and then commenting each line so we can better understand what you're trying to accomplish.

Resources