2

I am new to NASM (and assembler in general) and I am looking for way to get console size (number of console cols and rows) in NASM. Like AH=0Fh and INT 10h: http://en.wikipedia.org/wiki/INT_10H

Now, I understand, that in NASM (and linux in general) I can not do BIOS interruption, so there have to be other way.

The idea is to print some output to fill the screen and then wait for user to press ENTER until print more output.

Ján Stibila
  • 619
  • 3
  • 12
  • _"in NASM ... I can not do BIOS interruption"_. It has nothing to do with NASM, it's just that your target OS doesn't let you. For your question regarding the terminal size, see http://stackoverflow.com/questions/1022957/getting-terminal-width-in-c – Michael Mar 30 '15 at 07:42
  • *"in NASM (and linux in general)"* see that in parentheses? Also, I said I am new to not only NASM but assembler in general, please, if you know any sollution, let it be in NASM, not in C – Ján Stibila Mar 30 '15 at 07:47
  • @JánStibila that is what Michael did. Knowing the C function `ioctl`, you can then find the equivalent assembly `syscall` for the function. In this case: `__NR_ioctl`. It's 32-bit interrupt is `54`, the 64-bit equivalent is `16`. You can then look at the `ioctl` man page an look at what inputs it takes. You will load those values into the registers indicated and make the call. The order and registers involved (i.e. the **calling convention**) will differ depending whether you are working in a 32 or 64 bit environment. – David C. Rankin Mar 30 '15 at 07:55
  • To find the syscall number (e.g. `__NR_ioctl` ##), you generally look in the assembly header files (e.g. `/usr/include/asm/unistd_32.h` or `unistd_64.h`). The directory it they live in differs from distro & release, but you can always find them with `find` (e.g. `find /usr/include -type f -name unistd_64.h` ) – David C. Rankin Mar 30 '15 at 07:58

2 Answers2

2

If you are programming in Linux, then you must use the available system calls to achieve your aims. It's not that there are no interrupts. The system call itself is executed with an interrupt call. Outside of the kernel, however, you will be unable to access them and, since the kernel runs in protected mode, even if you could they likely wouldn't do what you would expect.

To your question, however. To obtain the console size you would need to make use of the ioctl system call. This is accessed with the value of 0x36 in EAX. I'd suggest that you have a read through the manual page for ioctl and you may also find this system call table very useful!

David Hoelzer
  • 15,862
  • 4
  • 48
  • 67
1

This is a problem I've got to deal with a time ago. The code for unistd.inc and termio.inc can be found here in the includes folder. The program can be found and the makefile you can find in de tree programs/basics/terminal-winsize.

The vaules for rows and columns you can get on any terminal (console). xpixels and ypixels you can get only from some terminals. (xterm yes, gnome-terminal depends). So if you don't get the x and y pixels (screensize) on from some terminals, the terminal is text-based I guess. Correct me if it has another reason for this behaviour.

You can convert this program easily to 32 bits since it make use of nasmx macros for the syscalls,. The only thing you have to do is to replace the 64 bit registers in 32 bit registers and put some parameters in the right register. Look for agguro on github to see all include files.

I hope this is helpfull to you

; 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
Agguro
  • 348
  • 3
  • 11
  • I no longer need it. It was for school project so I wouldn't use 3rd parties includes anyway (point was to learn how to do it). But thanks for answer, hopefully it'll help somebody else (and maybe one day i'll take some time to study provided codes) – Ján Stibila May 22 '15 at 09:25