【问题标题】:P3 Assembly - Printing values of vectorP3 汇编 - 打印向量的值
【发布时间】:2026-01-10 01:20:03
【问题描述】:

我在 P3 Assembly 中完成了一段代码,它遍历一个向量并打印该向量中的所有数字。问题是代码没有打印向量的第 9 个值......我找不到问题。有人能帮我吗?这是我的代码:

; TEMPORIZACAO
DELAYVALUE      EQU     F000h

; STACK POINTER
SP_INICIAL      EQU     FDFFh

; INTERRUPCOES  (INTERRUPTS)
TAB_INT0        EQU     FE00h
TAB_INT1        EQU     FE01h
MASCARA_INT EQU FFFAh

; I/O a partir de FF00H
DISP7S1         EQU     FFF0h
DISP7S2         EQU     FFF1h
LCD_WRITE   EQU FFF5h
LCD_CURSOR  EQU FFF4h   
LEDS            EQU     FFF8h
INTERRUPTORES   EQU     FFF9h
IO_CURSOR       EQU     FFFCh
IO_WRITE        EQU     FFFEh

LIMPAR_JANELA   EQU     FFFFh
XY_INICIAL      EQU     0000h
FIM_TEXTO       EQU     '@'


ORIG    8000h
VarTexto1       STR     'Valores do vector: ',FIM_TEXTO


ORIG    8030h
vetor   STR  67, 13, ffddh, 99, 12, 112, FFA6h, 65, 6AFFh
; 67, 13, -35, 99, 12, 112, -90, 65, 27391

 ORIG    0000h
 JMP     inicio

LimpaJanela:    PUSH R2             ; **CLEAR SCREEN
            MOV     R2, LIMPAR_JANELA
    MOV     M[IO_CURSOR], R2
            POP R2
            RET

PrintVec:   PUSH    R1
            PUSH    R2
            PUSH    R3
            PUSH    R4
            PUSH    R5
            MOV     R5, M[SP+8]   ; Pointer to the start of the string
            MOV     R2, M[SP+7]   ; Location of the first XY character
            MOV     R4, M[SP+9]   ; Pointer to the first elemnt of the vector
            MOV     R3, M[SP+10]  ; Size of the vector
Ciclo:      MOV     M[IO_CURSOR], R2
            MOV     R1, M[R5]
            CMP     R1, FIM_TEXTO
            BR.Z    Write
            CALL    EscCar
            INC     R5
            INC     R2
            BR      Ciclo
            ADD     R2, 1
Write:      CALL    PrintNum
            INC     R4
            ADD     R2, 6
            DEC     R3
            BR.NZ   Write
            POP     R4
            POP     R3
            POP     R2
            POP     R1
            RETN    2                ; Actualiza STACK

PrintNum:   PUSH    R1
            PUSH    R3
            PUSH    R5
Convert:    MOV     R3, 10
            MOV     R5, M[R4]
            ADD     R5, R0
            BR.NN   LABEL2
            MOV     M[IO_CURSOR], R2  
            MOV     R1, '-'
            CALL    EscCar
            NEG     R5
 LABEL2:    ADD     R2, 4
 LABEL3:    MOV     M[IO_CURSOR], R2      
            DIV     R5, R3
            MOV     R1, R3
            ADD     R1, 48
            CALL    EscCar
            MOV     R3, 10
            DEC     R2
            CMP     R5, 0
            BR.NZ   LABEL3
            POP     R1
            POP     R3
            POP     R5
            RETN    2                ; Actualiza STACK

EscCar:     MOV     M[IO_WRITE], R1
            RET                     

;===============================================================================
;                                Programa prinicipal
;===============================================================================
inicio:     MOV     R1, SP_INICIAL
            MOV     SP, R1
            CALL    LimpaJanela         ; Clear screen
            PUSH    9
            PUSH    vetor
            PUSH    VarTexto1           ; Push parameters onto stack
            PUSH    XY_INICIAL          ; Push parameters onto stack
            CALL    PrintVec
;===============================================================================

【问题讨论】:

  • ...这是什么汇编语言?它看起来有点像8081,也许吧?大学的东西?是你的教授发明的?
  • 是的……它是大学的 P3 模拟器……algos.inesc-id.pt/arq-comp/…
  • 手册是葡萄牙语的,所以帮助不大。 STR 指令有什么作用?从您声明vetor(及其下方的注释)的方式来看,似乎每个元素的大小至少为16 位。但是在Write 循环中,您似乎将元素视为单个字节,因为您只在增加地址时才执行INC R4
  • @Michael 这似乎是一个 16 位处理器,带有 16 位地址总线。增量 1 移动到下一个可寻址字。

标签: assembly vector ascii processador-p3


【解决方案1】:

您的函数PrintNum: 没有PUSHPOP 注册R2,用于输出的光标位置。它以不是很明显的方式摆弄R2。这只是一个猜测,但它会导致文本对齐失败,以至于第 9 个元素不可见。

所以在PrintNum:的入口/出口处添加PUSH R2POP R2

顺便说一句:您必须在进入时记录函数的寄存器参数,并在退出时更改寄存器。不这样做是一个基本的菜鸟失败。

【讨论】:

    【解决方案2】:

    RETN指令的使用存在一些问题。在函数 PrintVec 中应该是 RETN 4,因为您从堆栈中获取了四个值(当您执行 MOV R5, M[SP+8] /MOV R2、M[SP+7]/MOV R4、M[SP+9]/MOV R3、M[SP+10]等)。在函数PrintNum中,你只需要指令RET,因为你没有从堆栈中获取任何值

    【讨论】: