Pregunta

Can anyone run this program, or try to help me understand why my counter isnt updating?

I am supposed to read in text from a prompt and find the length of the text and output it with a colon before printing out the actual text entered.

If the first time I type in "test" the length is 4, but then when it loops back to start it asks me to input again, it outputs the correct text, but the counter doesnt change unless the text is longer.

So, if i type "I", it will output length of 4, since test is longer and is 4. But if I type "Control" which is 7 letters, it will update the counter to 7.

OUTPUT:

Enter: Hey
 3:Hey
Enter: Test
 4:Test
Enter: Control
 7:Control
Enter: Hey
 7:Hey      <---- Length should be 3!

Thank you!

.orig x3000             ; Starting point of the program.

BR start            ; Branch to the start routine.

newln:  .stringz "\n"
msg1:   .stringz "Enter: "

; Prints out the instructions to the user and reads some user input.

start:

lea r0, newln           ; Load address of newline into R0.
puts                    ; Print newline.

lea r0, msg1            ; Load address of message3 into R0.
puts  

lea r2, MESSAGE         ; Load starting point address of MESSAGE.
and r1, r1, #0          ; Initialize R1 to zero.

input:
getc                        ; Read in a single character to R0.
out
add r5, r0, #-10        ; Subtract 10 because enter key is 10.
BRz printint                ; If zero, branch to checkChar routine.
                            ; Else continue the loop.
str r0, r2, #0          ; Store char in MESSAGE.
add r2, r2, #1          ; Increment index of MESSAGE.
add r1, r1, #1          ; Increment input counter.
BR input                ; Unconditional branch to input.

checkChar:
lea r5, inv81           ; Load address of inv68 into R6.
ldr r5, r5, #0          ; Load contents of inv68 into R6 (R6 now holds     -68).
add r0, r3, r5          ; Add -68 to the value in R3, to check if it's 'q'.
BRz quit                ; If zero, branch to decrypt.



;
;print integer starts here
;
printint:
ld      r3,psign
jsr STRLEN
    ADD     r7, r0, #0     ; get the integer to print

    brzp    nonneg
    ld      r3,nsign
    not     r7,r7
    add     r7,r7,1
nonneg:
    lea     r6,buffer  ; get the address of o/p area
    add     r6,r6,#7   ; compute address of end of o/p
    ld      r5,char0   ; get '0' to add to int digits
loop1:
    and     r0,r0,#0   ; init quotient for each divide
loop2:
    add     r7,r7,#-10 ; add -10
    brn     remdr      ; until negative
    add     r0,r0,#1   ; incr to compute quotient
    br      loop2      ; repeat
remdr:
    add     r7,r7,#10  ; add 10 to get remainder
    add     r7,r7,r5   ; convert to ascii
    str     r7,r6,0    ; place ascii in o/p
    add     r7,r0,#0   ; move quot for next divide
    brz     end        ; if done then print
    add     r6,r6,#-1  ; move to prev o/p position
    br      loop1      ; repeat
end:
add     r6,r6,#-1  ; move to prev o/p position
    str     r3,r6,0    ; place sign
    add     r0,r6,#0   ; move address of 1st char 
    puts               ; into r0 and print

output:
ld r5, colon
and r3,r3, 0;
add r0, r3, r5;
out

lea r2, MESSAGE         ; Load (starting) address of MESSAGE.

outputLoop:
ldr r0, r2, #0          ; Load contents of address at MESSAGE index into R0.
out                     ; Print character.
add r2, r2, #1          ; Increment MESSAGE index.
add r1, r1, #-1         ; Decrease counter.

BRp outputLoop          ; If positive, loop.

br start
quit:

halt  ; Halt execution.

STRLEN:
 LEA    R2, MESSAGE ;R1 is pointer to characters
 AND    R0, R0, #0  ;R0 is counter, initially 0
     LD R5, char0


LOOP:    ADD     R2, R2, #1 ;POINT TO NEXT CHARACTER
 LDR     R4, R2, #0 ;R4 gets character input
 BRz     FINISH
 ADD     R0, R0, #1
 BR  LOOP

FINISH: 
 ADD     R0, R0, #1
 ret

MESSAGE:  .blkw         99          ; MESSAGE of size 20.
inv48:    .fill         #-48        ; Constant for converting numbers from     ASCII to decimal.
inv81:    .fill     #-81        ; Constant for the inverse of 'Q'.
buffer:   .blkw   8          ; o/p area
null:     .fill   0          ; null to end o/p area
char0:    .fill   x30
colon     .fill   x3A
nsign     .fill   x2d
psign     .fill   x20
  .end
¿Fue útil?

Solución

At the end of your example, the contents in memory starting at message are: Heytrol0000000

It looks to me like the problem is that in STRLEN we compute the length of the string by counting until we reach the first character that is 0. There are 7 characters in "Heytrol".

However, when we are storing the message, we count the number of characters that we have read in (kept in r1). When we print the string later on, we use the value in r1, so we don't end up printing any of the "extra" characters.

To fix this, I'd either output the value in r1 that was computed while reading the string as its length (get rid of the STRLEN code completely) or make sure that when we read the enter in the input loop, we write a zero into the string before going and printing:

input:
getc                    ; Read in a single character to R0.
out
add r5, r0, #-10        ; Subtract 10 because enter key is 10.
BRz finishString        ; If zero, branch to finishString routine.
                        ; Else continue the loop.
str r0, r2, #0          ; Store char in MESSAGE.
add r2, r2, #1          ; Increment index of MESSAGE.
add r1, r1, #1          ; Increment input counter.
BR input                ; Unconditional branch to input.

finishString:
and r0, r0, #0          ; set r0 to zero so we can store it
str r0, r2, #0          ; write zero (from r0) into the end of the string
BR printint             ; Now, branch to checkChar routine.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top