2

我正在用 NASM 编写简单的时钟程序。我通过 iTerm 在 OSX 下使用 Ubuntu 14.10 Vagrant box。终端是 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[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:~$

如果我clr通过添加进行更改,[1A或者[1B似乎将行删除到远高于或低于所需的水平:

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:~$

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

4

1 回答 1

1

我怀疑您的问题与隐含在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
于 2015-06-04T18:32:44.637 回答