好,我尝试清除MARS(mips汇编程序)的默认提示i / o,真诚地,不确定如何制作这个。在程序运行期间,我可以使用哪个代码或系统调用来刷新屏幕?
编辑:抱歉信息不佳。我说"模拟MIPS控制台输出/输入"存在于MARS中。我的问题是,如果在程序运行期间可以清除此控制台,并且任何代码实现都可以。答案 0 :(得分:0)
有两种基本方法可以做到这一点,但它们都涉及捕获clear
命令的输出[或使用其他TTY控制序列ala libcurses
]。在下面的示例中,我捕获了clear
命令的输出并对其执行了十六进制转储以获取clear: .byte ...
的数据
以下只是清除屏幕并输出经过的秒数,屏幕清晰的简单演示。其他xterm ESC
序列也是可能的,就像在任何C程序中一样。
如果我们在命令行模式下调用mars
:mars 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