You are not logged in.

#1 2009-04-17 07:58:13

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Cat in x86 Assembly

Awhile back, I couldn't figure out assembly, I even made a post somewhere around here asking for help with retrieving argc. Anyhow, I made a few programs in assembly and the one I am proud would be simple in any other language, like 5 lines in C I think, but in assembly, it was about 45 lines, haha. big_smile So I feel like sharing it.

.section .data
.section .bss
        .equ SIZE, 1
        .lcomm BUFFER, SIZE
.section .text

.globl _start

_start:

open:
        movl    $5, %eax        # open() system call
        movl    8(%esp), %ebx   # first argument
        movl    $0, %ecx        # intended for reading
        movl    $0666, %edx     # permission
        int     $0x80

read:
        movl    %eax, %ebx      # store fd for read()
        movl    $3, %eax        # read() system call
        movl    $BUFFER, %ecx   # store buffer address
        movl    $SIZE, %edx     # buffer size
        int     $0x80
    
        cmpl    $0, %eax        # EOF
        jle     close           # close

display:
        movl    %ebx, %ebp      # store fd into %ebp
        movl    $4, %eax        # write() system call
        movl    $1, %ebx        # fd STDOUT
        int     $0x80
    
        movl    %ebp, %eax      # move fd into %eax
        jmp     read            # continue reading

close:
        movl    $6, %eax        # close() system call
        movl    %ebp, %ebx      # move fd back into %ebx
        int     $0x80

exit:
        movl    $1, %eax        # exit() system call
        xorl    %ebx, %ebx      # return 0
        int     $0x80

Beautiful. wink I actually commented this too. Anyhow, hate, rate, or so on. By the way, AT&T syntax > Intel. I used to program in Perl. :s

Last edited by Aprz (2009-04-17 08:02:38)

Offline

#2 2009-04-21 08:52:50

gnud
Member
Registered: 2005-11-27
Posts: 182

Re: Cat in x86 Assembly

Here is my cat, supporting fancy stuff such as multiple arguments, or reading from stdin.

I wrote it ages ago, so I'm not sure I can answer any questions smile
It should be portable across unices ( big_smile ) since it uses a set of macros (not mine) for system calls and such. The strlen part is also not mine. Btw, intel syntax smile

Also, it's full of bugs, for example when printing error messages. Fun all around.

%include "system.inc"

%assign BUFSIZE 0x2000

DATASEG
    openerrmsg: db 'Error opening file '
    openerrlen: equ $-openerrmsg
    readerrmsg: db 'Error reading file.'
    readerrlen: equ $-readerrmsg
    newline: db 0xa
    newlinelen: equ $-newline

UDATASEG
    buf resb BUFSIZE

CODESEG

START:
    pop ebp ; number of arguments
    pop eax ; program name (argv)
    dec ebp ; we dont care about the program name
    cmp ebp, 0
    jle read_stdin ;no file names
    jmp next_file


next_file: ;check for more files in argv
           ;moves file name * to ebx, or exits
    cmp ebp, 0
    jle exit_done
    pop ebx ; move to next element in argv
    dec ebp ; decrement number of args
read_file:
    sys_open ebx, O_RDONLY ; open file for reading
    
    cmp eax, -1 ;check for error during open call
    jle open_error ;print error and die

    call read_loop ;read FD in eax
    jmp next_file ;check for more files

exit_done:
    sys_exit 0

; file name we could not open is in ebx
open_error:
    sys_write STDERR, openerrmsg, openerrlen
    mov eax, ebx ;pointer to file name
    call strlen
    sys_write STDERR, [ebx], eax
    sys_write STDERR, newline, newlinelen
    sys_exit 1


read_stdin:
    mov eax,STDIN
    call read_loop
    sys_exit 0


;reads fd in eax
;prints to stdout
read_loop:
    mov edi, eax
begin_read:
    sys_read edi, buf, BUFSIZE
    cmp eax, 0
    je escape_loop
    jl read_error
    sys_write STDOUT, buf, eax
    jmp begin_read

escape_loop:
    ret
;

read_error:
    sys_write STDERR, readerrmsg, readerrlen
    sys_write STDERR, newline, newlinelen
    sys_exit 1
  
    
;finds the length of the string pointed to by eax.
;stores result in eax
;touches ecx, al and edi
strlen:
    mov edi, eax    ;string pointer in edi
    sub ecx, ecx    ;clear out ecx
    sub al, al      ;clear out al
    not ecx         ;ecx = -1, or 2^32

    ;counts number of bytes before we find the value
    ;pointed to by al (0)
    cld
    repne scasb

    ;use two's complement logic to find the number of bytes
    ;the number of bytes is equal to (ecx*-1)-2
    ;could be written as
    ;neg ecx
    ;dec ecx
    ;dec ecx
    not ecx
    dec ecx
    
    ;per contract, store result in eax
    mov eax, ecx
    ret
; end strlen

Offline

#3 2009-04-22 09:40:51

essence-of-foo
Member
Registered: 2008-07-12
Posts: 84

Re: Cat in x86 Assembly

display:
        movl    %ebx, %ebp      # store fd into %ebp

Is there a specific reason why you use ebp to store a value?
ebp should contain the stack frame's base-adress. So using it for different purposes may (and probably will) create problems when using function calls that create a new stack frame on top of the current frame.

Offline

#4 2009-04-22 14:18:17

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Cat in x86 Assembly

No real reason that I could think of, just temporary storage that was easier than having to move more values around, which I figured would slow it down.

Offline

#5 2009-04-22 19:51:53

Varreon
Member
Registered: 2008-07-03
Posts: 95

Re: Cat in x86 Assembly

Arpz, what was the assembler you used? I was looking to get into assembly language programming, but I heard that gas isn't the best tool to use.

Offline

#6 2009-04-22 20:32:02

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Cat in x86 Assembly

Varreon wrote:

Arpz, what was the assembler you used? I was looking to get into assembly language programming, but I heard that gas isn't the best tool to use.

What he wrote is AT&T syntax so he probably uses good 'ol `as` (from binutils)
AT&T is not preety for some, but I myself find it really sexy looking smile. There's not a whole lot of difference between intel and AT&T so don't worry...
What makes AT&T "better" is the fact that dissasembling with gdb or whatever outputs using this syntax..so it's a bit of a plus to understand it


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#7 2009-04-22 23:36:35

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Cat in x86 Assembly

Wra!th wrote:

What makes AT&T "better" is the fact that dissasembling with gdb or whatever outputs using this syntax..so it's a bit of a plus to understand it

This is a point that would make me consider switching. But other than that I prefer Intel syntax just because I think it looks nicer. I use nasm.

Disclaimer: I'm an assembly n00b, but I'm learning slowly. It's ridiculously fun smile

Offline

#8 2009-04-23 05:35:05

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Cat in x86 Assembly

HashBox wrote:
Wra!th wrote:

What makes AT&T "better" is the fact that dissasembling with gdb or whatever outputs using this syntax..so it's a bit of a plus to understand it

Disclaimer: I'm an assembly n00b, but I'm learning slowly. It's ridiculously fun smile

Fun but useless smile (unless you're planning on doing some hardcore device drivers, some exploits, or..why not..an OS...)
I left asm way behind..it's not worth the time spent

Last edited by Wra!th (2009-04-23 05:36:13)


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#9 2009-04-23 06:24:02

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Cat in x86 Assembly

Wra!th wrote:

Fun but useless smile (unless you're planning on doing some hardcore device drivers, some exploits, or..why not..an OS...)
I left asm way behind..it's not worth the time spent

Well I'm not sure about device drivers, but exploits and low level OS code intrigue me, so why not smile
Also, I've been playing with KolibriOS a little lately, which for those of you unaware is an OS written entirely in assembly, but that is getting a little off topic tongue

Offline

#10 2009-04-23 07:11:48

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Cat in x86 Assembly

Yes, I used GAS.

Computer science and programming is what I study and do for entertainment and that's its only use to me, haha, I am training to be EMT-1 (hopefully a paramedic later on) right now so I doubt I'll be using Linux to do CPR or anything like that, haha. I heard assembly was a lot of fun so I decided to learn it. What really got me started on assembly though was my friend started doing assembly for NASM. Another friend was forced to take a class on MASM for his computer science degree. I decided to be different and use GAS. The greatest benefit with GAS for me though was because I already had GCC that meant I already had GAS which is why I chose GAS, haha.

If you can write in AT&T syntax, you can write in Intel, vise versa. It's not hard to convert. I'd say that if I had a favorite though, it would still be AT&T because I find the prefixes a very nice way to represent your coding(which is one reason why I like programming in Perl too - I mainly program in assembly or C though) such as $ meaning it is a value, a % being the registers, and even though I program in C with "int i = 0" as in location = value, I think of things more like "cp /old/path/ /new/path/" which is funny because that's actually how the whole value things works in assembly, you copy it, haha, even though that's not a programming example, that's exactly how I think of it.

Oh, I forgot to say that another reason I wanted to learn assembly was because I am reading about the Linux kernel in "Understanding the Linux Kernel Edition 3" and the first coding snipplets it gives is in assembly.

My goal with C and x86 Assembly is to rebuild parts my operating system hence why I made the shell which was a very important first step for me in my opinion. big_smile Open source is mostly useless if you can't program and it's a lot of fun to use stuff that you make. Even though my shell has no tab completion, I still use it, and it urges myself to add that feature in, haha.

Last edited by Aprz (2009-04-23 07:13:27)

Offline

#11 2009-04-23 09:20:31

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Cat in x86 Assembly

I loved that post Aprz, especially the last two paragraphs, it fits me very well.
I love learning for the sake of learning, but being able to program at any level is a very useful skill, even if you use Windows (maybe even _especially_ if you use Windows). Being able to code up small hacks or apps to help you be productive is the coolest thing ever in my opinion, and does give a huge sense of satisfaction big_smile
I suppose this does apply more in the open source world, if you find something that you don't quite like about an application, you can just grab the source and modify it. In fact, I find the hardest part about doing that is often getting the source to compile in the first place, rather than making the changes to it smile

Last edited by HashBox (2009-04-23 09:22:07)

Offline

#12 2009-04-23 09:33:29

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: Cat in x86 Assembly

I still have a soft spot for assembler, though I don't use it much.  I don't think it's at all useless.  At the very least it's a great learning exercise which can lead to deeper understanding of lots of things.  The program stack, dynamic linking, ELF file structure, etc in the software direction.  Hardware interrupts, cycles, threading, input/output in the hardware/computer architecture direction.  Etc, etc... There are still practical uses.  Like reverse engineering, for malware anaylsis, or embedded microcontrollers, which are in almost everything now... maybe you could program your own defibrillator wink

Anyways, I had played with your cat program, to learn AT&T syntax and try using POPAD for the first time:

        # EDI must be set to 0
        .macro stack_args A, B, C, D
        PUSHL   $\A             # EAX
        PUSHL   $\C             # ECX
        PUSHL   $\D             # EDX
        PUSHL   \B              # EBX
        
        PUSHL   %EDI            # ESP (ignored)
        PUSHL   %EDI            # EBP
        PUSHL   %ESI            # ESI (keep our input fileno)
        PUSHL   %EDI            # EDI
        .endm

        .section .bss
        .equ buffer_max, 1024
        .lcomm buffer, buffer_max

        .section .text
        .globl _start

_start:
        POP     %ECX            # error if no arguments given
        DEC     %ECX
        JZ      error

        POP     %EAX
        POP     %EAX        

        stack_args 5, %EAX, 0, 0666
        POPAL                   
        INT     $0x80           # syscall open()

        TEST    %EAX, %EAX
        JS      error           # exit if open returns -1

        MOVL    %EAX, %ESI      # store fileno in ESI
        
        XORL    %EAX, %EAX
        INCL    %EAX            # creates args for read() on stack
        stack_args 4, %EAX, buffer, buffer_max

                                # creates args for write() on stack
        stack_args 3, %ESI, buffer, buffer_max
        
readprint_loop:
        POPAL
        INT     $0x80           # syscall read()
        TEST    %EAX, %EAX
        JS      error           # error if returned < 0
        JZ      close           # close if 0 bytes were left

        MOVL    %EAX, 4*5(%ESP) # store bytes read into write's args

        POPAL
        INT     $0x80           # syscall write()
         
        TEST    %EAX, %EAX
        JS      error           # error if returned <= 0
        JZ      error           
        
        SUBL    $64, %ESP       # rewind ESP to read's args
        JMP     readprint_loop

close:
        MOVL    $6, %EAX        # close() system call
                                # move fd back into %ebx
        MOVL    %ESI, %EBX
        INT     $0x80
        
        XORL    %EBX, %EBX      # return 0
exit:
        MOVL    $1, %EAX        # exit() system call
        INT     $0x80

error:
        XORL    %EBX, %EBX
        INC     %EBX
        JMP     exit

I had hoped it would be smaller but its 36 bytes bigger at a wopping 416 bytes! Oh dear!  I mostly program perl now, and I see what you mean with the sigils!  I like it.  The one thing where AT&T is worse is with the memory addressing... ugly.

Offline

#13 2009-04-23 10:54:35

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Cat in x86 Assembly

Nice! I like it smile

Offline

#14 2009-04-23 12:51:16

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Cat in x86 Assembly

Hehe found some stuff I did a while back
A 31 byte demo of a 'tv' lost signal thingy (16 bit...dos..)

format binary as 'com'
org 100h
start:    mov    al, 12h
    int    10h
    push    word 0xA000
    pop    es
L1:    mov    di, es
    mov    dl, 200
L2:    mov    cx, 320
L3:    movsb
    loop    L3
    in    al, 060h
    cmp    al, 01
    je    exit
    dec    dl
    jz    L1
    jmp    L2
exit:    ret

Frolic! big_smile

format binary as 'com'
      org  0x100
main: mov  ax, 0x0013 ; MODE 13 Graphics
      int  10h

      push word 0xA000; 0xA000 == begin of video mem
      pop  es         ; set es to point to the video memory

L1:   mov  ax, 0
L2:   mov  cx, 64000  ; 320*200
      repz stosb
      push ax         ; preserve ax
      in   al, 060h   ; get keyboard
      cmp  al, 01     ; is ESCAPE?
      je   exit       ; exit if yes
      pop  ax         ; restore ax
      inc  ax
      cmp  ax, 7
      je   L1
      jmp  L2

exit: mov  ax, 0x004C ; exit with error code 0
      int  21h

Linux hardcoded ELF, writes hello, world to file: compiles to about 144 bytes

BITS 32
    org    0x08048000
ehdr:
    db    0x7F, "ELF", 1, 1, 1
times 9    db     0
    dw    2
    dw    3
    dd    1
    dd    _start
    dd    phdr - $$
    dd    0
    dd    0
    dw    ehdrsz
    dw    phdrsz
    dw    1
    dw    0
    dw    0
    dw    0
ehdrsz    equ    $ - ehdr

phdr:
    dd    1
    dd    0
    dd    $$
    dd    $$
    dd    filesz
    dd    filesz
    dd    5
    dd    0x1000
phdrsz    equ    $ - phdr

_start:    

    mov ebx, fnm
    mov eax, 8; create file
    mov ecx, 00644Q; got it from some tut..ecx has to hold the file persmisions..that octal = RW RW RW
    int 80h
    
    mov ebx, eax;eax holds the file descriptor got from "create()"
    mov eax, 4; write
    mov ecx, msg
    mov edx, msz
    int 80h
    mov eax, 6; close file
    int 80h

    xor eax, eax
    inc eax
    xor ebx, ebx
    int 80h

filesz    equ $ - $$

section .data
    msg: db "Hello, world!", 10
    msz: equ $ - msg
    fnm : db "file.txt"
ebx@ebx-desktop:~$ nasm -f bin tinywrite.asm -o tinywrite
ebx@ebx-desktop:~$ chmod +x tinywrite
ebx@ebx-desktop:~$ strip -s -X -R .comment -R .bss tinywrite
ebx@ebx-desktop:~$ wc -c tinywrite
144 tinywrite

I wrote these 2 years ago...don't expect to be much...


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#15 2009-04-23 13:52:41

HashBox
Member
Registered: 2009-01-22
Posts: 271

Re: Cat in x86 Assembly

I think I'll have to get a dosbox or something set up and have a play with this big_smile

Offline

#16 2009-04-23 15:01:18

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Cat in x86 Assembly

Ah, the programming section rocks compare to the rest of the Arch forums, haha. Everywhere else I post, they all treat me like a noob. "Aprz, this is how you compile a kernel". Annoys me. sad I know they can't tell I know from looks, but they jump straight to conclusion or just flat out say stupid things. Just want to say you guys rock (and the folks who posted in my shell post mostly, but I didn't like some of the post in there). I take things too personally. big_smile I need to write something else in assembly so I can feel cool again.

Last edited by Aprz (2009-04-23 15:02:04)

Offline

#17 2009-04-23 20:47:37

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Cat in x86 Assembly

Aprz wrote:

but I didn't like some of the post in there)

10 bucks say that reffers to my posts tongue


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#18 2009-04-24 08:15:36

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Cat in x86 Assembly

You're good. I forgot you were the one who said that, haha. Are you sure it is using bash. I mean, that's why I used fork() to create a process and then use that with execvp() as you see in the source. I have tried it without initiating bash, but I still kept bash for the init scripts since my shell cannot handle that yet. I swear that what you're thinking that would be using the shell is system(), not the exec() family. big_smile

I would be sad if I am totally wrong, but I am up for learning. wink

Last edited by Aprz (2009-04-24 08:16:26)

Offline

#19 2009-04-24 09:12:34

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Cat in x86 Assembly

Aprz wrote:

You're good. I forgot you were the one who said that, haha. Are you sure it is using bash. I mean, that's why I used fork() to create a process and then use that with execvp() as you see in the source. I have tried it without initiating bash, but I still kept bash for the init scripts since my shell cannot handle that yet. I swear that what you're thinking that would be using the shell is system(), not the exec() family. big_smile

I would be sad if I am totally wrong, but I am up for learning. wink

Not I didn't say it's exactly like running system(). haven't used fork much so I could be awfully wrong smile


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#20 2009-04-24 11:14:06

gnud
Member
Registered: 2005-11-27
Posts: 182

Re: Cat in x86 Assembly

In response to the AT&T/intel debate - newer GDB can be made to show intel syntax.

Just

set disassembly-flavor intel

Offline

#21 2009-04-24 11:30:41

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: Cat in x86 Assembly

gnud wrote:

In response to the AT&T/intel debate - newer GDB can be made to show intel syntax.

Just

set disassembly-flavor intel

Blasphemy! sad


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

#22 2009-04-25 07:01:48

Aprz
Member
From: Newark
Registered: 2008-05-28
Posts: 277

Re: Cat in x86 Assembly

AT&T syntax still rocks my socks. \o/

Offline

#23 2009-04-25 12:06:36

gnud
Member
Registered: 2005-11-27
Posts: 182

Re: Cat in x86 Assembly

Hey -- feel free to hate on intel syntax. Just don't bring up GDB support as a point in favour of AT&T smile

Offline

Board footer

Powered by FluxBB