How to clear screen on protected mode - linux

I'm using NASM for Linux and I'd like know how, in the protected mode, you can clear the screen. I found a solution using the int10h, but on the protected mode I can only use int80h. Thanks in advance.

You can write \x1b[2J to the standard output so the terminal get cleared and fix the cursor position using \x1b[H, for example in nasm:
global _start
section .data
clr db 0x1b, "[2J", 0x1b, "[H"
clrlen equ $ - clr
section .text
_start:
mov eax, 4
mov ebx, 1
mov ecx, clr
mov edx, clrlen
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
for gnu assembler:
.globl _start
.data
clr : .ascii "\x1b[2J\x1b[H"
clrlen = . - clr
.text
_start:
movl $4, %eax
movl $1, %ebx
movl $clr, %ecx
movl $clrlen, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80

Related

Assembler - adding big (128b) numbers (AT&T assembly syntax) - where to store results?

I am trying to add two 128 bits numbers using ATT assembly syntax in linux ubuntu 64b and I am debugging it in gdb so I know that after every loop the result of adding two parts is correct but how to store all 4 results together?? I was considering adding every result to the stack but I can't add the register content to the stack, right? Am I even doing it correctly? I am a real beginner in assembler but I need it for uni :/
EXIT_SUCCESS = 0
SYSEXIT = 1
number1:
.long 0x10304008, 0x701100FF, 0x45100020, 0x08570030
number2:
.long 0xF040500C, 0x00220026, 0x321000CB, 0x04520031
.global _start
_start:
movl $4, %edx
clc
pushf
_loop:
dec %edx
movl number1(,%edx,4), %eax
movl number2(,%edx,4), %ebx
popf
adcl %ebx, %eax
cmp $0, %edx
jne _loop
popf
jnc _end
push $1
_end:
mov $SYSEXIT, %eax
mov $EXIT_SUCCESS, %ebx
int $0x80

Jump instruction doesn't work

data
tekst: .ascii "heLLo WoRlD 93a9s\0"
tekst_len = . - tekst
.text
.global _start
_start:
mov $tekst_len, %edx
petla:
cmp $tekst_len, %edx
je koniec
cmpb $'a', tekst(,%edx,1)
jg zamien #?????????????????????????????????????
inc %edx
jmp petla
zamien:
movb $'X', tekst(,%edx,1)
inc %edx
jmp petla
koniec:
movl $4, %eax
movl $1, %ebx
movl $tekst, %ecx
movl $tekst_len, %edx
int $0x80
I have such a problem: the instruction 'jg zamien' doesn't work. No matter what condition I choose 'jl', 'je' it never executes. Can someone tell me why?
This is the reason:
mov $tekst_len, %edx
petla:
cmp $tekst_len, %edx <-- edx will equal $tekst_len here on the first iteration
je koniec
You're always jumping to koniec on the first iteration of the loop.
The mov should probably be mov $0,%edx.

Convert x32 AT&T Assembly to Intel (Linux)

I have a quick ASM conversion question.
pop %ebx
xor %eax, %eax
movb %al, 7(%ebx)
movl %ebx, 8(%ebx)
movl %eax, 12(%ebx)
xor %eax, %eax
movb $11, %al
leal 8(%ebx), %ecx
leal 12(%ebx), %edx
int $0x80
My try:
pop ebx
xor eax, eax
mov [ebx+7], al
mov [ebx+8], ebx
mov [ebx+12], eax
xor eax, eax
mov al, 11
lea ecx, [ebx+8]
lea edx, [ebx+12]
int 80h
The main issue I'm having is the 7(%ebx) (and simmilar). Does it actually mean [ebx+7]?

How to read input string from keyboard using assembly language

I'm trying to write a simple program that takes string from the keyboard, then prints it to the screen. So far I couldn't make it work.
Here's the code:
.section .rodata
output: .string "you entered %s\n"
input: .string "%s"
.text
.globl main
.type main, #function
main:
pushl %ebp
movl %esp, %ebp
subl $100, %esp
pushl $input
call scanf
movl %ebp, %esp
subl $100, %esp
pushl $output
call printf
xorl %eax, %eax
movl %ebp, %esp
popl %ebp
ret
When I execute it, the output is you entered (null) for any given input.
when I set the offset of subl $100, %esp command (the one before call print) to subl $104, %esp I get you entered %s, and when the offset is set to 108 I get you entered *gibberish*.
I feel like it's a game where I need to guess where scanf saved the string on the stack (why isn't it where it should be?).
I am using IA32 instruction set.
Any help would be greatly appreciated.
Basically there are 3 problems in your program:
subl $100, %esp
pushl $input
# Error 1:
# As Frank Kotler already wrote at this point
# only $input is stored on the stack; however
# the address of the buffer must also be on
# the stack (see Frank Kotler's comment)
call scanf
movl %ebp, %esp
# Error 2:
# Now the buffer is below ESP.
# Because interrupts use the kernel stack they
# will not overwrite the memory below ESP.
# However signals will destroy the memory below
# ESP!!
#
# Instead of the lines:
# movl %ebp, %esp
# subl $100, %esp
#
# You should use something like this:
# add $8, %esp
# or:
# lea -100(%ebp), %esp
#
subl $100, %esp
# Error 3:
# As for "scanf" the second argument
# is missing on the stack
pushl $output
call printf
[org 0x0100]
jmp start
;=======Data===================================
s1: db 'Enter String: $'
s2: db 'Reversed String:$'
linefeed: db 10, '$'
;=======Read string and store into stack=======
start: mov dx, s1
mov ah, 09h
int 21h
mov dx, linefeed
mov ah, 09h
int 21h
mov si,0
mov bx,0
again: mov ah, 01h
int 21h
cmp al,byte 0dh
je endread
Page 8 of 10
mov bl,al
push bx
inc si
cmp si,15
je endread
jmp again
endread: Push si
;=======Read from stack and print to screen=====
mov dx, linefeed
mov ah, 09h
int 21h
mov dx, s2
mov ah, 09h
int 21h
mov dx, linefeed
mov ah, 09h
int 21h
pop si
r1: pop bx
mov dl,bl
mov ah, 02h
int 21h
dec si
cmp si,0
jne r1
mov dx, linefeed
mov ah, 09h
int 21h
mov ax, 0x4c00 ;terminate program
int 21h

Segmentation fault in Assembly and string

I am trying to make a simple program in assembler, but I do not understand why, I get a fault.
I' ve a 64 bit machine running Ubuntu 12.04, and "as" as a assembly compiler.
My goal merely is to print the string "Hello" on screen.
I wrote this:
#print.s
.section .data
.globl StringToPrint
StringToPrint: .asciz "Hello"
.globl _start
_start:
movq $4, %rax
movq $1, %rbx
movq $StringToPrint, %rcx
movq $5, %rdx
int $0x80
_done:
ret
But that's what I get:
$ as print.s -o print.o
$ ld print.o -o print
$ ./print
Hello[1] 10679 segmentation fault (core dumped) ./print
Why do you think this happens? Any idea?
Here is the fix :
#print.s
.section .data
.globl StringToPrint
StringToPrint: .asciz "Hello"
.globl _start
_start:
movl $5, %edx # string length
movl $StringToPrint, %ecx # pointer to string to write
movl $1, %ebx # file handle (stdout)
movl $4, %eax # system call number (sys_write)
int $0x80 # Passes control to interrupt vector
#sys_exit (return_code)
movl $1, %eax #System call number 1: exit()
movl $0, %ebx #Exits with exit status 0
int $0x80 #Passes control to interrupt vector
As Michael has already said you need to call sys_exit to avoid segmentation fault .
Edit :
Here is good to mention that int 0x80 invokes 32-bit system calls .
Using int 0x80 for syscall on x64 systems is used for backward compatibility to allow 32-bit applications to run .
On 64-bit systems will be correct to use syscall instruction .
Here is a working version :
.section .data
StringToPrint: .asciz "Hello"
.section .text
.globl _start
_start:
movq $1, %rax # sys_write
movq $1, %rdi # stdout
movq $StringToPrint, %rsi # pointer to string to write
movq $5, %rdx # string length
syscall
movq $60, %rax # sys_exit
movq $0, %rdi # exit code
syscall
The calling conventions differ between 32 and 64 bit applications in Linux as well as other OSs. Additionally, for Linux the system call numbers are also different. This is how you invoke the write system call in Linux amd64:
; sys_write(stdout, message, length)
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, message ; message address
mov rdx, length ; message string length
syscall
Additionally, your application needs to call sys_exit to terminate, not return using ret. Read the calling conventions for your platform.

Resources