根据偏移不起作用将字符存储到缓冲区中

时间:2016-11-18 17:08:37

标签: assembly lc3

我正在开发一个程序,它接受一个数字的输入,并在基数为10,2,4和8中输出。从输入中获取数字的逻辑很简单,以及这样的转换给定基数的数字。我所坚持的部分需要将转换后的数字存储到缓冲区中,最后使用TRAP x22

读取

这是我的想法:

  • 首先,我将空间块(FINNUM)的地址加载到R5
  • 同时将BUFFER(x0000,尝试停止输出)加载到R6
  • 将R6存储到R5以获取空终止符
  • 减少R5
  • 将DIGITS的第一个值加载到另一个寄存器R4

  • 然后执行分部

  • 将R4和R3(R4的偏移)添加到R6
  • 再次将R6存储到R5中以存储获得的值
  • 减少R5
  • 进行正确的算法检查(如果商为零,则不再进行除法,退出循环)

  • 将R5放入R0

  • 输出

我尝试过我在下面的代码中所描述的内容,但是我对输出感到喋喋不休(并且奇怪的是整个DIGITS字符串)我在这里检查的是什么?显然存储操作不起作用,但我不明白为什么不存在。请让我知道我可以在哪里开始修复此错误。

;Subroutine PRINT*************************************************************
;Displays an unsigned integer in any base up to 16, e.g. binary, octal, decimal
;Parameters - R0: the integer - R1: the base
PRINT
    ST  R0, PR0
    ST  R1, PR1
    ST  R2, PR2
    ST  R3, PR3
    ST  R4, PR4
    ST  R5, PR5
    ST  R6, PR6
    ST  R7, PR7 

    LEA R5, FINNUM  ;Prepare pointer to storage
    LEA R6, BUFFER
    STR R6, R5, #0
    ADD R5, R5, #-1
    LD  R4, DIGITS  ;Prepare pointer to the digits  
SDIV
    JSR DIVIDE      
    ADD R6, R4, R3  ;Add the remainder with digits to get number
    STR R6, R5, #0  ;Store number into buffer
    ADD R5, R5, #-1 ;Decrement
    ADD R0, R2, #0  ;Pass quotient into R0
    BRP SDIV        ;If number is at least 1, then divide again

    ADD R0, R5, #0  ;If we got here, then we should have the converted number
    TRAP    x22     ;Last but not least we display

    LD  R7, PR7
    RET
;Data
DIGITS  .STRINGZ "0123456789ABCDEF" ;Digits
FINNUM  .BLKW   18          ;Output Buffer
BUFFER  .FILL   x0000           ;Null
PR0 .BLKW   1
PR1 .BLKW   1
PR2 .BLKW   1
PR3 .BLKW   1
PR4 .BLKW   1
PR5 .BLKW   1
PR6 .BLKW   1
PR7 .BLKW   1

如果您需要,请输入以下代码:

.ORIG   x3000
    LEA R0, MPROMPT
    TRAP    x22
LOOP
    JSR GETDEC      ;Input an unsigned (decimal) integer
    ADD R0, R0, #0  ;Exit if the input integer is 0
    BRZ EXIT

    JSR NEWLN       ;Move cursor to the start of a new line
    AND R1, R1, #0  ;R1 = 10 (output base 10 DECIMAL)
    ADD R1, R1, #10 
    JSR PRINT       ;Print the integer in decimal

    JSR NEWLN       ;Move cursor to the start of a new line
    AND R1, R1, #0  ;R1 = 2 (output base 2 BINARY)
    ADD R1, R1, #2
    JSR PRINT       ;Print the integer in binary

    JSR NEWLN       ;Move cursor to the start of a new line
    AND R1, R1, #0  ;R1 = 8 (output base 8 OCTAL)
    ADD R1, R1, #8
    JSR PRINT       ;Print the integer in octal

    JSR NEWLN       ;Move cursor to the start of a new line
    AND R1, R1, #0  ;R1 = 16 (output base 16 HEXADECIMAL)
    ADD R1, R1, #15
    ADD R1, R1, #1
    JSR PRINT       ;Print the integer in hexadecimal

    JSR NEWLN       ;Move cursor to the start of a new line

    BRNZP   LOOP
EXIT                ;Loop exit point
    TRAP    x25     ;HALT program execution
MPROMPT .STRINGZ "Enter a sequence of unsigned integer values\nEnter 0 To Quit\n"

;Subroutine NEWLN*************************************************************
;Advances the console cursor to the start of a new line
NEWLN   
    ST  R7, NEW7    ;Save working registers
    ST  R0, NEW0

    LD  R0, NL      ;Output a newline character
    TRAP    x21

    LD  R0, NEW0    ;Restore working registers
    LD  R7, NEW7
    RET         ;Return
;Data
NL  .FILL   x000A   ;Newline character
NEW0    .BLKW   1   ;Save area - R0
NEW7    .BLKW   1   ;Save area - R7

;Subroutine GETDEC************************************************************
;Inputs an unsigned integer typed at the console in decimal format
;The input value is returned in R0
GETDEC
    ;Save Values of ALL Registers that don't need to change
    ST  R1, GET1
    ST  R2, GET2
    ST  R3, GET3
    ST  R4, GET4
    ST  R5, GET5
    ST  R6, GET6
    ST  R7, GET7    ;Save R7 to be able to return to main

    AND R3, R3, #0  ;Prepare a value
    LEA R0, GPROMPT
    TRAP    x22
GETDKEY
    TRAP    x20     ;To input a keystroke   
    ADD R2, R0, #-10    ;Subtract new keystroke by 10 (new line, or enter)
    BRZ GFINIS      ;If R2 is 0 we just pressed enter, so we break out
    TRAP    x21     ;Echo keystroke     
    ADD R2, R0, #0  ;Get the number back
    AND R2, R2, #15 ;We mask to only get the first four bits
    ADD R3, R3, R3  ;1st addition: x + x = 2x
    ADD R4, R3, #0  ;Store the 2x
    ADD R3, R3, R3  ;2nd addition: 2x + 2x = 4x
    ADD R3, R3, R3  ;3rd addition: 4x + 4x = 8x
    ADD R3, R3, R4  ;4th addition: 8x + 2x = 10x
    ADD R3, R3, R2  ;10x + new number
    BRNZP   GETDKEY     ;Go back to get next number
GFINIS
    ADD R0, R3, #0  ;Put number into R0

    ;Restore the values of registers that don't need change
    LD  R1, GET7
    LD  R2, GET7
    LD  R3, GET7
    LD  R4, GET7
    LD  R5, GET7
    LD  R6, GET7
    LD  R7, GET7    ;Get back the value of R7
    RET
;Data
GPROMPT .STRINGZ "Enter an unsigned integer> "  ;Input Prompt
GET1    .BLKW   1
GET2    .BLKW   1
GET3    .BLKW   1
GET4    .BLKW   1
GET5    .BLKW   1
GET6    .BLKW   1
GET7    .BLKW   1

;Subroutine PRINT*************************************************************
;Displays an unsigned integer in any base up to 16, e.g. binary, octal, decimal
;Parameters - R0: the integer - R1: the base
PRINT
    ST  R0, PR0
    ST  R1, PR1
    ST  R2, PR2
    ST  R3, PR3
    ST  R4, PR4
    ST  R5, PR5
    ST  R6, PR6
    ST  R7, PR7 

    LEA R5, FINNUM  ;Prepare pointer to storage
    LEA R6, BUFFER
    STR R6, R5, #0
    ADD R5, R5, #-1
    LD  R4, DIGITS  ;Prepare pointer to the digits  
SDIV
    JSR DIVIDE      
    ADD R6, R4, R3  ;Add the remainder with digits to get number
    STR R6, R5, #0  ;Store number into buffer
    ADD R5, R5, #-1 ;Decrement
    ADD R0, R2, #0  ;Pass quotient into R0
    BRP SDIV        ;If number is at least 1, then divide again

    ADD R0, R5, #0  ;If we got here, then we should have the converted number
    TRAP    x22     ;Last but not least we display

    LD  R7, PR7
    RET
;Data
DIGITS  .STRINGZ "0123456789ABCDEF" ;Digits
FINNUM  .BLKW   18          ;Output Buffer
BUFFER  .FILL   x0000           ;Null
PR0 .BLKW   1
PR1 .BLKW   1
PR2 .BLKW   1
PR3 .BLKW   1
PR4 .BLKW   1
PR5 .BLKW   1
PR6 .BLKW   1
PR7 .BLKW   1

;Subroutine DIVIDE************************************************************
;Perform unsigned integer division to obtain Quotient and Remainder
;Parameters (IN)  : R0 - Numerator,  R1 - Divisor
;Parameters (OUT) : R2 - Quotient,   R3 - Remainder
DIVIDE  
    ST  R5, DIV7
    ST  R6, DIV7
    ST  R7, DIV7

    AND R2, R2, #0
    ADD R3, R0, #0
    ADD R5, R1, #0
    NOT R5, R5
    ADD R5, R5, #1 ;2's complement to R5 to be able to substract    
DSUBT
    ADD R6, R3, R5 ;R6 = R3 - R5
    BRN ENDDIV
    ADD R2, R2, #1 ;If here, R0 was bigger than R1, we can add 1
    ADD R3, R3, R5 ;Subtract again to avoid losing the remainder
    BRNZP   DSUBT
ENDDIV  
    LD  R5, DIV7
    LD  R6, DIV7
    LD  R7, DIV7
    RET        ;Return
;Data
DIV7    .BLKW   1

    .END

这是我可以用Java完成的事情,但是我对这种语言太新了,坦率地说,我仍然试图理解在函数执行之前存储寄存器的问题并在最后加载它们。我之所以提到这一点,是因为它导致了输入(即返回主执行)和分区的问题。请让我知道,并提前感谢您的帮助

编辑:将功能更改为从BUFFER地址开始,添加18以获取最后一个可用存储空间,然后将存储过程修改为先减少然后存储。此外,所有寄存器都在开头存储,然后在最后重新加载,以防万一:

;Subroutine PRINT*************************************************************
;Displays an unsigned integer in any base up to 16, e.g. binary, octal, decimal
;Parameters - R0: the integer - R1: the base
PRINT
    ST  R0, PR0
    ST  R1, PR1
    ST  R2, PR2
    ST  R3, PR3
    ST  R4, PR4
    ST  R5, PR5
    ST  R6, PR6
    ST  R7, PR7 

    LEA R6, FINNUM
    ADD R6, R6, #10 ;Add to get to the end of the buffer
    ADD R6, R6, #8  ;Add to get to the end of the buffer
    AND R5, R5, #0  ;To make sure R5 is cleared
    LD  R4, DIGITS  ;Prepare pointer to the digits  
SDIV
    JSR DIVIDE      
    ADD R5, R4, R3  ;Add the remainder with digits to get number
    ADD R6, R6, #-1 ;Decrement to get to the next one
    STR R5, R6, #0  ;Store number into buffer
    ADD R0, R2, #0  ;Pass quotient into R0
    BRP SDIV        ;If number is at least 1, then divide again

    ADD R0, R6, #0  ;If we got here, then we should have the converted number
    TRAP    x22     ;Last but not least we display

    LD  R0, PR0
    LD  R1, PR1
    LD  R2, PR2
    LD  R3, PR3
    LD  R4, PR4
    LD  R5, PR5
    LD  R6, PR6
    LD  R7, PR7
    RET
;Data
DIGITS  .STRINGZ "0123456789ABCDEF" ;Digits
FINNUM  .BLKW   18          ;Output Buffer
BUFFER  .FILL   x0000           ;Null
PR0 .BLKW   1
PR1 .BLKW   1
PR2 .BLKW   1
PR3 .BLKW   1
PR4 .BLKW   1
PR5 .BLKW   1
PR6 .BLKW   1
PR7 .BLKW   1

LC3在ADD R0, R2, #0之后立即停在STR。该程序是否存储在适当的位置?

0 个答案:

没有答案