2016-06-13 48 views
2

好,我试着清除MARS(mips汇编程序)的默认提示I/O,真诚地,不知道如何做到这一点。我可以使用哪些代码或系统调用来刷新屏幕程序运行期间?如何刷新mars mips中的提示?

编辑:对不起,信息不好。我说的是MARS中存在的“模拟MIPS控制台输出/输入”。我的问题是在程序运行期间是否可以清除这个控制台,以及任何代码实现。

+0

你所说的[刷新]屏幕意思? stdout控制台? MMIO控制台?位图显示?如果你可以编辑你的问题来更具体,它会帮助我[和你]。你可以发布你已有的相关mips代码吗?你是什​​么意思的“默认提示”I/O?此外,您可以根据自己目前正在做什么以及您希望程序的整体执行情况来重述您的问题。你只想在C中输出诸如'fputs(...,stdout)'的消息吗? –

+0

对不起,没有资料。我说的是MARS中存在的“模拟MIPS控制台输出/输入”。我的问题是在程序运行期间是否可以清除这个控制台,以及任何代码实现。 –

回答

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 

然而,如果我们在调用mars GUI模式(例如mars),系统调用4将转到其正常窗口窗格[而不是了解类似于xterm的转义序列],因此,上述wi ll 不是工作。

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

这是更为复杂,因为我们需要做手工的一切,但它的工作原理:

.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