NASM获得控制台大小

时间:2015-03-30 07:38:46

标签: nasm

我是NASM的新手(以及一般的汇编程序),我正在寻找在NASM中获取控制台大小(控制台列数和行数)的方法。像AH = 0Fh和INT 10h:http://en.wikipedia.org/wiki/INT_10H

现在,据我所知,在NASM(以及一般的Linux)中,我无法进行BIOS中断,因此必须有其他方式。

想法是打印一些输出以填满屏幕,然后等待用户按ENTER直到打印更多输出。

1 个答案:

答案 0 :(得分:1)

这是我前一段时间要处理的问题。可以在includes文件夹中找到unistd.inc和termio.inc的代码here。可以在de tree programs / basics / terminal-winsize中找到该程序和makefile。

您可以在任何终端(控制台)上获得的行和列的值。 xpixels和ypixels只能从某些终端获得。 (xterm是的,gnome-terminal取决于)。因此,如果您没有从某些终端获取x和y像素(屏幕大小),我猜这个终端是基于文本的。如果它有其他原因导致这种行为,请纠正我。

您可以轻松地将此程序转换为32位,因为它使用nasmx宏进行系统调用。您唯一需要做的就是替换32位寄存器中的64位寄存器并将一些参数放入正确的寄存器中。在github上查找agguro以查看所有包含文件。

我希望这对你有所帮助

; Name:         winsize
; Build:        see makefile
; Run:          ./winsize
; Description:  Show the screen dimension of a terminal in rows/columns.

BITS 64
[list -]
    %include "unistd.inc"
    %include "termio.inc"
[list +]

section .bss
    buffer:    resb 5
    .end:
    .length:   equ  $-buffer
    lf:        resb 1

section .data

   WINSIZE winsize
   ; keep the lengths the same or the 'array' construction will fail!
   array:     db   "rows    : "
              db   "columns : "
              db   "xpixels : "
              db   "ypixels : "
   .length:   equ  $-array
   .items:    equ  4
   .itemsize: equ  array.length / array.items

section .text
    global _start
_start:
    mov     BYTE[lf], 10                    ; end of line in byte after
buffer
    ; fetch the winsize structure data
    syscall ioctl, STDOUT, TIOCGWINSZ, winsize
    ; initialize pointers and used variables
    mov     rsi, array                 ; pointer to array of strings
    mov     rcx, array.items              ; items in array
.nextVariable:    
    ; print the text associated with the winsize variable
    push    rcx                        ; save remaining strings to process
    push    rdx                        ; save winsize pointer
    syscall write, STDOUT, rsi, array.itemsize
    pop     rax                        ; restore winsize pointer
    push    rax                        ; save winsize pointer
    ; convert variable to decimal
    mov     ax,  WORD[rax]                  ; get value form winsize structure
    mov     rdi, buffer.end-1
.repeat:    
    xor     rbx, rbx                   ; convert value in decimal
    mov     bx, 10
    xor     rdx, rdx
    div     bx
    xchg    rax, rdx
    or      al, "0"
    std
    stosb
    xchg    rax, rdx
    cmp     al, 0
    jnz     .repeat
    push    rsi                        ; save pointer to text
    ; print the variable value    
    mov     rsi, rdi
    mov     rdx, buffer.end                 ; length of variable
    sub     rdx, rsi
    inc     rsi
    syscall write, STDOUT, rsi, rdx
    pop     rsi
    pop     rdx
    ; calculate pointer to next variable value in winsize
    add     rdx, 2
    ; calculate pointer to next string in strings
    add     rsi, array.itemsize
    ; if all strings processed
    pop     rcx                        ; remaining arrayitems
    loop     .nextVariable
    ; exit the program
    syscall exit, 0