如何刷新火星mips中的提示?

时间:2016-06-13 18:59:32

标签: mips mars

好,我尝试清除MARS(mips汇编程序)的默认提示i / o,真诚地,不确定如何制作这个。在程序运行期间,我可以使用哪个代码或系统调用来刷新屏幕?

编辑:抱歉信息不佳。我说"模拟MIPS控制台输出/输入"存在于MARS中。我的问题是,如果在程序运行期间可以清除此控制台,并且任何代码实现都可以。

1 个答案:

答案 0 :(得分:0)

有两种基本方法可以做到这一点,但它们都涉及捕获clear命令的输出[或使用其他TTY控制序列ala libcurses]。在下面的示例中,我捕获了clear命令的输出并对其执行了十六进制转储以获取clear: .byte ...的数据

以下只是清除屏幕并输出经过的秒数,屏幕清晰的简单演示。其他xterm ESC序列也是可能的,就像在任何C程序中一样。

如果我们在命令行模式下调用marsmars myfile.s,那么系统调用4将连接到xterm窗口,以下内容将起作用:

    .data
msg:    .asciiz     "hello world\n"
clear:  .byte   0x1B,0x5B,0x33,0x3B,0x4A,0x1B,0x5B,0x48,0x1B,0x5B,0x32,0x4A
eclear:
        .byte 0x00

    .text
    .globl main
main:

main_loop:
    # clear the screen
    la      $a0,clear
    li      $v0,4
    syscall

    # output a number
    move    $a0,$t7
    li      $v0,1
    syscall
    addiu   $t7,$t7,1

    # wait a bit
    li      $t6,500000
main_delay:
    subiu   $t6,$t6,1
    bnez    $t6,main_delay
    j       main_loop

但是,如果我们在GUI模式下调用mars(例如mars),系统调用4将转到其正常窗口窗格[ }序列]因此,上面的工作。

但是,如果我们从程序中打开/dev/tty,对它执行写入系统调用,我们可以将转义序列发送到包含xterm命令的mars窗口。

这是更复杂的,因为我们必须手工完成所有事情,但它有效:

    .data
ofile:  .asciiz     "/dev/tty"
msg:    .asciiz     "hello world\n"
clear:  .byte   0x1B,0x5B,0x33,0x3B,0x4A,0x1B,0x5B,0x48,0x1B,0x5B,0x32,0x4A
        .byte 0x00

sprintf_buf:
    .space  80
sprintf_bufe:

    .text
    .globl main
main:
    li      $v0,13                  # open file
    la      $a0,ofile               # filename to open
    li      $a1,1                   # 1=O_WRONLY
    li      $a2,0                   # mode [ignored]
    syscall
    move    $s7,$v0                 # remember open unit

main_loop:
    # clear the screen
    la      $a1,clear
    jal     fputs

    # format the progress number
    move    $a0,$t7
    addiu   $t7,$t7,1
    jal     sprintf

    # output the progress number
    jal     fputs

    # delay a bit
    li      $t0,500000
main_delay:
    subiu   $t0,$t0,1
    bnez    $t0,main_delay
    j       main_loop

# sprintf -- format a number
#
# RETURNS:
#   a1 -- pointer to buffer
#
# arguments:
#   a0 -- number to output
sprintf:
    la      $a1,sprintf_bufe        # get buffer pointer
    subi    $a1,$a1,1
    sb      $zero,0($a1)            # store EOS

    li      $t1,10                  # get decimal base

sprintf_loop:
    div     $a0,$t1                 # get both (num / 10) and (num % 10)
    mfhi    $t0                     # isolate digit (num % 10)

    # store ascii digit
    addi    $t0,$t0,'0'
    subiu   $a1,$a1,1
    sb      $t0,0($a1)              # store the digit

    mflo    $a0                     # num /= 10
    bnez    $a0,sprintf_loop

    jr      $ra

# fputs -- output string to "console"
#
# arguments:
#   s7 -- file descriptor
#   a1 -- pointer to string
fputs:
    move    $a2,$a1                 # get buffer address

# get string length
fputs_loop:
    lb      $t0,0($a2)              # get next char -- is it EOS?
    addiu   $a2,$a2,1               # increment length/buffer pointer
    bnez    $t0,fputs_loop          # no, loop

    subu    $a2,$a2,$a1             # get the length

    move    $a0,$s7                 # get file descriptor
    li      $v0,15                  # syscall for write
    syscall

    jr      $ra                     # return