asm babysteps on linux - int 80 std input

Programming, for all ages and all languages.
Post Reply
User avatar
eino
Member
Member
Posts: 49
Joined: Fri Sep 16, 2011 10:00 am
Location: Finland

asm babysteps on linux - int 80 std input

Post by eino »

Hi,

I'm checkin out asm development (and x86 asm in general) on Linux and while writing this hello world type program I run into a question of how to determine the length for int 80 functions 3 and 4 (especially for 3) when I want to read user input and then write it back to stdout. Also I cant seem to zero out my input variables/lables/memory locations (what is the correct term?) by xoring... And part of the previous input gets strangely printed on next inputs...

Thanks for your help! Hard work on filling the basic knowledge requirements for kernel dev =D

Code: Select all

global _start	;LD linker default entrypoint name

segment .data
	welcome_message		db	"Welcome! Please input some text: ", 0Ah
	welcome_length		equ $-welcome_message

	newline_message		db	"", 0Ah
	newline_length		equ $-newline_message

segment .bss
	user_input			resb	10
	user_input_length	equ $-user_input

segment .text
	_start:
		
		ask:

		;print message
		mov		eax, 4
		mov		ebx, 1
		mov		ecx, welcome_message
		mov		edx, welcome_length
		int		80h

		call	input_string
		
		jmp ask
		
		mov eax, 1        
    	mov ebx, 0        
    	int 80h

	input_string:
		
		pusha
		
		;Get user stdin
		mov		eax, 3
		mov		ebx, 1
		mov		ecx, user_input
		mov		edx, user_input_length ;How to determine this?
		int		80h

		
		;Print users input to stdout
		mov		eax, 4
		mov		ebx, 1
		mov		ecx, user_input
		mov		edx, user_input_length ;How to determine this?
		int		80h

		;print new line
		mov		eax, 4
		mov		ebx, 1
		mov		ecx, newline_message
		mov		edx, newline_length
		int		80h

		;Try to zero out all bits in user input
		;since they show up strangely in following inputs
		;fails thou
		mov		eax, user_input  ;wrong way to access?
		xor		eax, eax

		popa
		ret
Output:

Code: Select all

Welcome! Please input some text: 
Hello
Hello

Welcome! Please input some text: 
Hi
Hi
lo

Welcome! Please input some text: 
I'm Eino Tuominen from Finland, a web software dev learning low level stuff and reading / trying out kernel dev
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: asm babysteps on linux - int 80 std input

Post by iansjack »

It's better to use the term "system call" rather than "interrupt" for these functions. 3 and 4 are the system calls sys_read and sys_write. You can find full details of these system calls by Googling them. In answer to your specific question, ecx contains the address of a memory buffer that you have allocated, and edx the length of this buffer. In your case you allocated 10 bytes for the input buffer, so edx should be 10. When the function returns it will tell you how many bytes were actually read (10 or less) in eax.

To zero out any variables you just move 0 into them. Don't do that with user_input - that would zero the address of the buffer, which is not what you want. Just move a 0 into each of the 10 bytes of the buffer. Everyone seems to be hung up on using the xor trick to zero a register; I prefer to do an explicit move. It hardly uses any more memory or clock cycles and is clearer IMO; we don't live in the days of 16K RAM and 4.7MHz processors so don't have to get too precious about these things.

There are several good books and online tutorials about assembler programming. Read one or more of these rather than just trying to make sense of odd snippets of assembler code.
User avatar
eino
Member
Member
Posts: 49
Joined: Fri Sep 16, 2011 10:00 am
Location: Finland

Re: asm babysteps on linux - int 80 std input

Post by eino »

Thanks! I do have a few books I'm reading and the nice thing is that actually no snippets were copied on this one... Which is just the result of iteration on these things (reading/copy pasting) (and finally I feel like I'm getting a grasp on this)

Gonna try out your hint.
I'm Eino Tuominen from Finland, a web software dev learning low level stuff and reading / trying out kernel dev
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: asm babysteps on linux - int 80 std input

Post by iansjack »

One thing I should have added, and most strongly recommend, is to run your programs under a debugger (such as gdb on Linux). That way you can single-step through code and see exactly what is happening to registers and memory locations. It takes a little effort to learn how to use the debugger, but it's well worth it.
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: asm babysteps on linux - int 80 std input

Post by linguofreak »

eino wrote:Hi,

I'm checkin out asm development (and x86 asm in general) on Linux and while writing this hello world type program I run into a question of how to determine the length for int 80 functions 3 and 4 (especially for 3) when I want to read user input and then write it back to stdout. Also I cant seem to zero out my input variables/lables/memory locations (what is the correct term?) by xoring... And part of the previous input gets strangely printed on next inputs...
That's because you aren't clearing your input string, you're just loading its address into eax and then setting eax to 0 with the xor.

What you'd want to do is set eax to zero, edi to the address of your input string, ecx to the length of your input string, and use rep stosb to zero it.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: asm babysteps on linux - int 80 std input

Post by Antti »

iansjack wrote:To zero out any variables you just move 0 into them. Don't do that with user_input - that would zero the address of the buffer, which is not what you want. Just move a 0 into each of the 10 bytes of the buffer.
This is not going to make things less confusing. The label user_input is not pointing to a pointer of the buffer. The label value cannot be changed at run-time.

It is important to know how to zero buffers. However, in this case it is not needed. You have to know how many characters you get from the user and use that information for determining how many characters in the buffer are valid. Things will become clear very soon! Keep going.
User avatar
eino
Member
Member
Posts: 49
Joined: Fri Sep 16, 2011 10:00 am
Location: Finland

Re: asm babysteps on linux - int 80 std input

Post by eino »

Here's the solution. Thanks alot! Will most likely ask about something else soon =)

Code: Select all

global _start	;LD linker default entrypoint name

segment .data
	welcome_message		db	"Welcome! Please input some text: ", 0Ah
	welcome_length		equ $-welcome_message

	newline_message		db	"", 0Ah
	newline_length		equ $-newline_message

segment .bss
	user_input			resb	10
	user_input_length	equ $-user_input

segment .text
	_start:
		
		ask:

		;print message
		mov		eax, 4
		mov		ebx, 1
		mov		ecx, welcome_message
		mov		edx, welcome_length
		int		80h

		call	input_string
		
		jmp ask
		
		mov eax, 1        
    	mov ebx, 0        
    	int 80h

	input_string:
		
		pusha
		
		;Get user stdin
		mov		eax, 3
		mov		ebx, 1
		mov		ecx, user_input
		mov		edx, user_input_length ;How to determine this?
		int		80h

		
		;Print users input to stdout
		mov		edx, eax
		mov		eax, 4
		mov		ebx, 1
		mov		ecx, user_input
		int		80h

		;print new line
		mov		eax, 4
		mov		ebx, 1
		mov		ecx, newline_message
		mov		edx, newline_length
		int		80h
	
		;to make things clean, zero out the user_input
		mov		eax, 0
		mov		ecx, user_input_length ;tells rep how many times to stosb
		mov		edi, user_input ;the address of the buffer
		rep stosb ;repeat zeros to the buffer
		
		popa
		ret
I'm Eino Tuominen from Finland, a web software dev learning low level stuff and reading / trying out kernel dev
Post Reply