VT-100命令工作奇怪

我正在用NASM写简单的时钟程序。 我在OSX上通过iTerm使用Ubuntu 14.10 Vagrant框。 terminal是xterm,所以应该是VT-100兼容。

我需要删除一行。 例如,我期望以下行为:

Hello, this is clock program 13:01:25 UTC+4 

下一刻:

 Hello, this is clock program 13:01:26 UTC+4 

我写了下面的函数。 打印:

 func_print: mov eax, sys_write mov ebx, stdout int 0x80 ret 

为了清楚:

 clr db 0x1b, "[K" clr_len equ $-clr ... func_clear: mov ecx, clr mov edx, clr_len call func_print 

为了保存和恢复职位,我使用VT-100及其命令: [7分别为[7[8

 csave db 0x1b, "[7" csave_len equ $-csave crestore db 0x1b, "[8" crestore_len equ $-crestore 

我的代码:

 global _start _start: mov ecx, welcome mov edx, welcome_len call func_print call func_print call func_save_cursor_pos mov dword [tv_sec], 2 mov dword [tv_usec], 0 call func_sleep call func_clear call func_restore_cursor_pos mov ecx, welcome mov edx, welcome_len call func_print jmp func_exit 

但是,结果是:

 vagrant@vagrant-ubuntu-trusty-64:~$ ./run.sh Hello, this is the clock program Hello, this is the clock program Hello, this is the clock program vagrant@vagrant-ubuntu-trusty-64:~$ 

如果我通过添加[1A[1B来更改clr ,那么似乎是将行删除得比所需的更高或更低:

 vagrant@vagrant-ubuntu-trusty-64:~$ ./run.sh Hello, this is the clock program Hello, this is the clock program Hello, this is the clock program vagrant@vagrant-ubuntu-trusty-64:~$ 

我该如何解决? 什么是正确的代码?

我怀疑你的问题是关系到新的一行暗示在welcome db "Hello, this is the clock program", 10 。 我不能确定,因为你没有发布你的代码的一部分。

我认为这会导致一个问题,因为换行符导致终端滚动 – 当我从我的版本中删除换行符时,它正常工作。 如果你只需要更新一行,就可以不用换行。

我怀疑保存和恢复操作是在屏幕上的字面物理位置上工作的,而不是通过换行滚动的逻辑位置。

但是,一般来说,我建议使用光标操作转义代码:

  • 当你准备重新绘制输出时,写入db 0x1b, "[nA"向上移动n行。 (你需要把号码放在那里)
  • 之后(或之后的任何一个换行符),写入db 0x1b, "[K"清除该行。 (你已经知道这一点,但为了完整性,我已经包括了它。)

我写了一个示例程序来实现这个,部分基于你的。 它显示:

 Hello, this is the clock program. Line two. 

然后,过了一会儿

 === TEST === More. 

接着

 === TEST 2 === Again. 

这种技术应该推广到任何合理的行数。

 BITS 32 section .text welcome db "Hello, this is the clock program", 10, "Line two.", 10 welcome_len equ $-welcome test_str db 0x1b, "[2A", 0x1b, "[K=== TEST ===", 10, 0x1b, "[KMore.", 10 test_len equ $-test_str test2_str db 0x1b, "[2A", 0x1b, "[K=== TEST 2 ===", 10, 0x1b, "[KAgain.", 10 test2_len equ $-test2_str func_print: mov eax, 4 mov ebx, 1 int 0x80 ret pause: ; Note: DON'T EVER USE THIS IN A REAL PROGRAM. This is not how you sleep properly. mov eax, 0 loop: inc eax cmp eax, 1000000000 jl loop ret global _start _start: mov ecx, welcome mov edx, welcome_len call func_print call pause mov ecx, test_str mov edx, test_len call func_print call pause mov ecx, test2_str mov edx, test2_len call func_print mov eax, 1 mov ebx, 0 int 0x80