[SOLVED] Assembly language printing integers to the stdout using int 0x80
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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
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.
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
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 ...
ForzaItalia2006, Sorry I should have rephrased the question. When I wrote :
Quote:
Originally Posted by yaami
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....
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
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 ...
yaami, you seem to be ignoring the correct answers that have been posted.
Quote:
Originally Posted by ForzaItalia2006
The second parameter is a (char *) and not an integer.
Quote:
Originally Posted by yaami
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.