Sunday, January 29, 2012

Getting some IO going with assembly and C

After a few days break I got back on into Assembly getting my newest code snippet put together.
This time I'm working mainly with IO specifically from and to the terminal (or console if your that way inclined ;) ).
I know this isn't pure Assembly but the API's written for the OS's arn't written in Assembly and with the drivers being rather complicated... well this was the easiest solution for a newbie (not to mention graphics card specific!).

Unfortunately to make this all work I had to modify the build script.
Basically instead of just linking the Assembly library to the end executable I had to compile it with gcc (can't have c libraries without a c compiler with the sources ext.).


What is the change exactly?
Simple, change
ld -s -o blog_first start.o

to
gcc -o blog_second start.o

and with that I also changed
./blog_first

to
./blog_second

I know I didn't have to change that last line but.. you know second code snippet might as well :p
That was the changes for build.sh.


The Assembly file (start.asm) had a number of changes.
For starters as we switched from linking to compiling with c then linking the main function (_start) had to be renamed to _main.


Heres the code!
start.asm

segment .data
   
    two_var_output db "%s%s", 0
    output db "You said ", 0
    input db "Please say something: ", 0
    hello_world db "Hello World!", 10, "Second blog article code", 10, 0
   
segment .bss
    result resb 0 ; Define a non initialised variable.
   
segment .text

        global  _main
        extern _printf, _gets ; Import printf and gets functions from c.
           
    _main:
        ; Write to the terminal our hello world statement.
        push dword hello_world ; Push variable hello_world on top of stack.
        call _printf ; Call printf function with paramaters being the stack.
        pop eax ; Pop the first (last to be put on) variable on the stack.
   
        ; Read a string from the terminal, this could be
        ;     any ASCII charactor and save it in input variable.
        push dword input ; Push the variable input on top of the stack.
        call _printf ; Call printf function with paramaters being the stack.
        pop eax ; Pop the first (last to be put on) variable on the stack.
       
        push result ; Push variable result on top of the stack
        ;                      (really just the pointer not the value as its not initalised).
        call _gets ; Call gets function with paramaters (Well pointer) being the stack.
        pop eax ; Pop the first (last to be put on) variable on the stack.
       
        ; We want to print out a message before what was entered (takes 3 paramaters).
        push dword result ; Push variable result on top of the stack (Now has a value!)
        push dword output ; Push the variable output on top of the stack.
        push dword two_var_output ; Push the variable two_var_output on top of the stack.
        call _printf ; Call printf function with paramaters being the stack.
        pop eax ; Pop the first (last to be put on) variable on the stack.
        pop eax ; Pop the first (last to be put on) variable on the stack.
        pop eax ; Pop the first (last to be put on) variable on the stack.
       
        mov eax, 0  
        ret

There is minimal commenting on explaining what is going on, but that will be explained in the next post.


What does that code actually do you probably are asking yourself (or me doesn't matter really).
Here is the terminal output / input
Hello World!
Second blog article code
Please say something:
You said

Yup that's all it does.
I hope this will be a great help during debugging.
But be warned when using printf with more then 1 argument the format string must be what it supports e.g. %x is an integer.

No comments:

Post a Comment