LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Assembly language printing integers to the stdout using int 0x80 (https://www.linuxquestions.org/questions/programming-9/assembly-language-printing-integers-to-the-stdout-using-int-0x80-817999/)

yaami 07-04-2010 04:40 PM

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.

steviebob 07-04-2010 09:53 PM

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.

steviebob 07-04-2010 11:27 PM

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>

yaami 07-05-2010 01:02 AM

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.

ForzaItalia2006 07-05-2010 09:30 AM

Quote:

Originally Posted by yaami (Post 4023971)
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 (Post 4023971)
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

yaami 07-06-2010 09:26 PM

ForzaItalia2006, Sorry I should have rephrased the question. When I wrote :
Quote:

Originally Posted by yaami (Post 4023971)
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.

dogpatch 07-06-2010 09:57 PM

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?

ForzaItalia2006 07-07-2010 09:55 AM

Quote:

Originally Posted by yaami (Post 4025734)
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 (Post 4025734)
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

johnsfine 07-07-2010 11:47 AM

yaami, you seem to be ignoring the correct answers that have been posted.

Quote:

Originally Posted by ForzaItalia2006 (Post 4024278)
The second parameter is a (char *) and not an integer.

Quote:

Originally Posted by yaami (Post 4025734)
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 (Post 4025745)
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.

yaami 07-08-2010 10:43 PM

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.


All times are GMT -5. The time now is 03:21 AM.