我正在用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