LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-04-2010, 04:40 PM   #1
yaami
LQ Newbie
 
Registered: Jul 2010
Posts: 10

Rep: Reputation: 0
Assembly language printing integers to the stdout using int 0x80


Hi all,

I'm good in programming in high level languages C/C++, python ... but a complete n00b when it comes to assembly. I want to print a single digit integer on to the screen using the int 0x80. I have loaded the number in the ecx(=5, say), size in edx (=4, lenght) and eax (=4) ebx (=1). I've added 48 to the contents of ecx, and then calling int 0x80, I thought should print 5 on the screen.

However it does not print anything. also gives no errors. I checked the contents of the ecx reg (gdb), it has 53.

Can someone tell me where the problem is. A snippet showing the this will be great. I've seen snippets using the c library (printf), but I want to see how it is done using int 0x80.

Thanks.

Last edited by yaami; 07-04-2010 at 04:42 PM.
 
Old 07-04-2010, 09:53 PM   #2
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Rep: Reputation: 16
Alright, I am rather new to Assembly myself, but I think I can help you. You want to print out the number "5" on the screen, am I right? Could you provide the code you are using? I will show you how I would do it:
Code:
;print out 5
	global _start
_start:
section .data			;Declare
	five:	db	"5",10		;This is declaring five to equal 5,
					;plus a linefeed character
	fiveL:	equ	$ - five	;Getting the length of "five"
section .text			:Code
	mov	eax, 4			;'write' syscall
	mov	ebx, 1			;'standard file format' or something
					;along those lines
	mov	ecx, five		;ecx=5
	mov	edx, fiveL		;edx=length of five
	int	80h			;program interrupt (prints out "5")

	mov	eax, 1			;'quit' syscall
	mov	ebx, 0			;Returns 0
	int	80h			;program interrupt (quits program, 
					;this time)
Oh, and this is the first actual "answer" I have posted here on LQ, I hope I helped! ^^

Of course, I'm using "int 80h" assuming you use linux. Look up the correct program interrupts if you use DOS or windows.

Last edited by steviebob; 07-04-2010 at 09:54 PM.
 
Old 07-04-2010, 11:27 PM   #3
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Rep: Reputation: 16
Oh, and before I forget, you have to compile and link the program. I use "nasm" for compiling and "ld" in a shell to link it. The way you do this is quite simple.
To build the program (say I called the script above "five.asm"), you type
Code:
nasm -f elf five.asm
This will build the program using the ELF program standard. This will create some crucial files. First, it will create "five.o", which is the built code, and a program, "five" (that's what it'll show up as if you use "ls"). These two are crucial to the next step, linking, which you perform as follows:
Code:
ld -s -o five five.o
This will link the executable, "five", with the built code, "five.o", so when you execute "five" it will look at "five.o" and execute those commands.
So remember, write the source code in a file with the suffix .asm, compile with
Code:
nasm -f elf <file.asm>
and link with
Code:
ld -s -o <file> <file.o>
 
Old 07-05-2010, 01:02 AM   #4
yaami
LQ Newbie
 
Registered: Jul 2010
Posts: 10

Original Poster
Rep: Reputation: 0
Hi steviebob,

Thanks for the reply, but the program snippet you wrote here is not actually printing a number. It is printing a char "5".

But let us say we have to write an ASM program which adds 2 numbers and prints the sum... in that case we do not have the sum in ascii by default. So what is done usually is put the ascii equivalent of the sum in the eax register (adding 48).

But when I do this it is not printing the number on stdout. I have done this using the stack reg's and the call printf statement. But I could not figure out how this is done using int 0x80.

Please let me know if you can find a solution to this.
Thanks.
 
Old 07-05-2010, 09:30 AM   #5
ForzaItalia2006
Member
 
Registered: Dec 2009
Location: Walldorf, Germany
Distribution: (X)Ubuntu, Arch, Gentoo
Posts: 205

Rep: Reputation: 67
Quote:
Originally Posted by yaami View Post
Thanks for the reply, but the program snippet you wrote here is not actually printing a number. It is printing a char "5".
Yes true, but that's exactly how numbers in registers get onto the screen. A display usually accepts only a certain character encoding (e.g. ASCII). Furthermore, you're missing the prototype of the write system call. The second parameter is a (char *) and not an integer. When you pass in the value '5', the kernel will assume that '5' is an address which is not true.

Quote:
Originally Posted by yaami View Post
But let us say we have to write an ASM program which adds 2 numbers and prints the sum... in that case we do not have the sum in ascii by default. So what is done usually is put the ascii equivalent of the sum in the eax register (adding 48).
Rigth, if you want to do that, you'll have to convert the sum of both numbers into a printable form. BTW, that's exactly what the '%d' specifier of printf(3) is doing. Convert an integer into a stream of characters.

So, the code of steviebob should serve as a base for your approach ...

Andi
 
Old 07-06-2010, 09:26 PM   #6
yaami
LQ Newbie
 
Registered: Jul 2010
Posts: 10

Original Poster
Rep: Reputation: 0
ForzaItalia2006, Sorry I should have rephrased the question. When I wrote :
Quote:
Originally Posted by yaami View Post
But let us say we have to write an ASM program which adds 2 numbers and prints the sum... in that case we do not have the sum in ascii by default. So what is done usually is put the ascii equivalent of the sum in the eax register (adding 48).
in the part of adding 48 to contents of eax I was trying to convert them to ascii. But it was not displaying. I thought that my way of converting to ascii was wrong, I assumed people would find it was wrong and let me know the correct procedure. But I think I assumed too much....

My question, from the very beginning, should have been how to convert from integer to ascii... pardon my poor way of framing the question....

Thanks.
 
Old 07-06-2010, 09:57 PM   #7
dogpatch
Member
 
Registered: Nov 2005
Location: Central America
Distribution: Mepis, Android
Posts: 490
Blog Entries: 4

Rep: Reputation: 238Reputation: 238Reputation: 238
Does int 80 expect cx to contain a character to print, as yaami seems to assume, or the address of a character string, as with steviebob's code?
 
Old 07-07-2010, 09:55 AM   #8
ForzaItalia2006
Member
 
Registered: Dec 2009
Location: Walldorf, Germany
Distribution: (X)Ubuntu, Arch, Gentoo
Posts: 205

Rep: Reputation: 67
Quote:
Originally Posted by yaami View Post
in the part of adding 48 to contents of eax I was trying to convert them to ascii. But it was not displaying. I thought that my way of converting to ascii was wrong, I assumed people would find it was wrong and let me know the correct procedure. But I think I assumed too much....
You should never make any assumptions about my or other's intelligence. Possibly you didn't notice, but most of us are humans and do make errors as well or misunderstand parts of the initial questions. :-)

BTW, I already told you why the value 5 can't work. I must admit that I over-read that you added 48, but that won't make any difference for the kernel, because neither adress 0x5 nor 0x33 will be addressable from the user-space.

Quote:
Originally Posted by yaami View Post
My question, from the very beginning, should have been how to convert from integer to ascii
You can't expect that we write this assembly routine for you and maybe you should try your favourite WEB engine to find an appropriate algorithm, but here's a very primitive one:

Code:
sum_to_display = <sum of your numbers>
digit_to_display = sum_to_display % 10
sum_to_display = sum_to_display / 10

print(digit_to_display)

loop until sum_to_display is zero
I hope that helps to understand the basic logic of the conversion. As I said, there might be more sophisticated algorithms, especially in assembly code ...

Andi
 
Old 07-07-2010, 11:47 AM   #9
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
yaami, you seem to be ignoring the correct answers that have been posted.

Quote:
Originally Posted by ForzaItalia2006 View Post
The second parameter is a (char *) and not an integer.
Quote:
Originally Posted by yaami View Post
My question, from the very beginning, should have been how to convert from integer to ascii.
No, you asked the right question: "Printing integers to stdout using int 0x80". You just ignored the answer.

Adding 48 is fine for converting a single digit number from an integer to ascii. You'll need more work for multi digit numbers. But it makes sense to first understand why the single digit number didn't display.

Quote:
Originally Posted by dogpatch View Post
Does int 80 expect cx to contain a character to print, as yaami seems to assume, or the address of a character string, as with steviebob's code?
It expects ecx to contain the address of the character(s), not to contain the character.

If your program computes the character(s) that you want displayed, it needs to store them somewhere in memory and put the address of where they were stored into ecx for the call to int 0x80.

Last edited by johnsfine; 07-07-2010 at 11:51 AM.
 
Old 07-08-2010, 10:43 PM   #10
yaami
LQ Newbie
 
Registered: Jul 2010
Posts: 10

Original Poster
Rep: Reputation: 0
johnsfine, thanks for the reply... I'll try it out by using a variable sum and the save the sum in it and then passing it to ecx...

Thanks all.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
hooking interrupts (int 0x80 and sysenter) hamedn Programming 5 09-30-2009 12:36 AM
printing 64bit integers in C yanivwehtam Programming 6 03-05-2009 08:56 AM
How to learn assembly language? darkangel29 Programming 8 01-12-2009 12:30 PM
Assembly Language, and networks grizzly Programming 5 12-11-2003 09:50 PM
SPARC assembly language jclark00001 Programming 3 02-26-2003 08:52 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:29 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration