Jump to content

Intro to Intel Assembly Language: Part 8

- - - - -

  • Please log in to reply
6 replies to this topic

#1
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Hello, and welcome back to my long-overdue eighth part of my tutorial series. If you haven't checked out the previous seven parts, you might want to unless you know what you're doing. Anyway, in this part I'll be going over some Linux system calls you can make in your assembly programs. This means you can use functions like mmap and other fun high-level sorta things in your assembly programs. So let's get started!
Side note: this is kinda short because I have to go do some errands in a bit. I'll write a longer tutorial about something sometime.

Interrupts vs. SYSENTER/SYSLEAVE
Linux used to use interrupt 80h to make its system calls; Intel introduced the SYSENTER and SYSLEAVE instructions to make things much faster. As SYSENTER and SYSLEAVE are somewhat confusing to the novice programmer (it requires writing to model-specific registers and a slew of other fun things), I'm going to stick with interrupts for now. As of this writing, the interrupts still work on my system.

Making a System Call
How do we make a system call in Linux? Well, we do it by passing certain values in registers. This convention always holds no matter what kind of call you're making. It goes something like this:

EAX - ID number of the system call you're making

EBX - argument 1

ECX - argument 2

EDX - argument 3

ESI - argument 4

EDI - argument 5

EBP - argument 6

If you only have three arguments, don't worry about the other registers; you don't have to zero them out or anything. You should not rely on the system saving your registers, so if you have anything you can't afford to lose--EBP being one of them--save it yourself. The only register you're guaranteed to get back is ESP. The rest of the arguments, if any, must be pushed on the stack following C convention (i.e. in reverse order).
So what about these ID numbers? There's a rather extensive list of them here. Notice that there's a heading called "Section 2 - system calls" on the main page. This means that when we get our search results, we're going to be looking for write(2) because that's the entry for write() in--guess what--section 2, our list of system calls.

So we do our search and find this:

Quote

ssize_t write(int fd, const void *buf, size_t count);
This means that we have our file descriptor as our first argument, a pointer to whatever it is that we're going to write as the second, and the number of bytes we want to write as our third. Translating that to our system call convention, we have:

mov     eax, 4

mov     ebx, (STDOUT's file descriptor)

mov     ecx, (pointer to our Hello World string)

mov     edx, (number of bytes to write)

int     80h

Not too much of a problem. The file descriptor for STDOUT is always 1. (STDIN, STDOUT, STDERR -> 0,1,2 respectively.) Getting a pointer in NASM is simple, as you just put the label name and NASM does the rest for you. As for the number of bytes, we're just going to cheat for now and count how many characters there are in the string "Hello, World!" It's 13 by my count, not including the terminating null. We don't need it. So our final system call is going to look like this:

mov     eax, 4

mov     ebx, 1

mov     ecx, sz_hello_world

mov     edx, 13

int     80h


.

.

.


; somewhere in your .data section

sz_hello_world: db "Hello, World!"


Neat, huh?

I trust you're able to put a program together around this, but in case you can't, here's the full code:

global main


section .code

main:

    push    ebp

    mov     ebp, esp

    

    mov     eax, 4

    mov     ebx, 1

    mov     ecx, sz_hello_world

    mov     edx, 15     ; see note below

    int     80h


    pop     ebp

    ret


section .data

    ; note that we don't care about the terminating null,

    ; but I'm sticking in a carriage return / linefeed to

    ; get a new line on the console.

    

    sz_hello_world: db "Hello, World!",0dh,0ah

Compile it with NASM, link with GCC, run it in your console...and behold the glory of Linux and assembly language. :)
A few side notes:
- You're going to want to check the return value (always EAX) to see if some error occurred. Negative values are always bad.
- To really make your print function useful, link with the standard library and call strlen (or roll your own) and stick the return value into EDX.
This also means that your strings now require the terminating null.

Questions? Comments? Insults? Feel free to post here so I can make further tutorials better.

Next In This Series
http://forum.codecal...ge-part-9a.html

Edited by dargueta, 18 November 2010 - 07:24 PM.
Wrong file descriptors mentioned and forgot link.

sudo rm -rf /

#2
marwex89

marwex89

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 10,720 posts
Nice, I just read through your series because I have decided to broaden my somewhat narrow ASM-horizon... I hope there will be a part 9 soon :)

+rep
Hey! Check out my new Toyota keyboaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

#3
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
I'll try...currently getting pummeled by 3 CS project classes...
sudo rm -rf /

#4
gokuajmes

gokuajmes

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 518 posts
Dargueta as far as i have searched , you seem to be the only person who posts Tutorial on ASM , Great Work dude !! i love asm too , Jet blazing speed that the application Run is what amazes me :D

#5
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Compilers are typically better than people nowadays, but it's still fun. Very useful for base work in operating systems and other low-level stuff.
sudo rm -rf /

#6
manux

manux

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 234 posts
Is there a 21st century tutorial on how to actually build asm? I mean, what I personally need is a tutorials that:
-tells how to setup your 2010 computer (not DOS or Amiga)
-tells how to choose the good assembler (for Intel syntax and not AT&T syntax)
-give quick tips about what commands to use for nasm/tasm/fooasm, and/or for gcc (should I do nasm -foo bar.asm? People don't like reading doc just to make a Hello World ;) )
-give a few simple working examples for C/asm interaction

When I was younger I sometimes went to a guy's lab and he showed me some assembly tricks live, so I am not totally unfamiliar with the language, but a couple times I've tried to setup everything on my own, run a Hello World, but without success...

Very good tutorials btw, I read them all and they are informative and well structured.

#7
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,705 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Why thank you. If I haven't written one of those by next week, harass me. I'm currently working on Part 9 (basic graphics), so hang on for more fun. I'll try to get it out this weekend, but I can't promise anything.
sudo rm -rf /




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users