Find the answer to your Linux question:
Results 1 to 10 of 10
Greetings all! Long time no see, and all that.... Lately, I've decided to teach myself some assembly language. I know assembly is a little useless these days, given the optimising ...
  1. #1
    Linux Guru smolloy's Avatar
    Join Date
    Apr 2005
    Location
    CA, but from N.Ireland
    Posts
    2,413

    x86 assembly

    Greetings all! Long time no see, and all that....

    Lately, I've decided to teach myself some assembly language. I know assembly is a little useless these days, given the optimising power of a good C compiler, but I think it will help teach me about exactly what goes on inside my computer when programming in higher level languages.

    I have just successfully compiled my first program, and I thought I'd share it. When assembled, it simply echos back the first argument given to the executable. Useless, but I thought it was a good start!

    Let me hear your comment and criticisms. How could I make it better? Shorter? More efficient?

    (By the way, it's written to be assembled by nasm on x86 linux.)

    Code:
    global _start
    
    section .data
            term    db      " ", 10    ; a newline character to terminate the string
            length  equ     $-term
    
    section .text
    
    _start:
            pop     edi             ; argc
            pop     edi             ; argv[0]
            pop     edi             ; the first real arg, the string to be echoed 
            push    edi            ; push it back onto the stack for later use
    
            xor     ecx, ecx      ; zero ecx
            not     ecx             ; all ones
            xor     al, al           ; zero al
            cld                        ; The following lines find the length of the string help
            repne   scasb         ; in edi (i.e. the input)
            not     ecx
            mov     edx,ecx
    
            mov eax, 4              ; write to file
            mov ebx, 1              ; STDOUT handle
            pop     ecx                ; pop the input back off the stack
            int 80h                 ; execute the syscall
    
            mov eax, 4              ; write to file
            mov ebx, 1              ; STDOUT handle
            mov ecx, term          ; the newline
            mov edx, length
            int 80h                    ; syscall
    
            xor ebx, ebx            ; send 0 as 'exit code'
            mov eax, 1              ; terminate process
            int 80h                 ; execute the syscall
    Registered Linux user #388328 || Registered LFS user #15880
    AMD 64 X2 4600+ :: 2X1GB DDR2 800 :: GeForce 9400 GT 512MB :: ASUS M2N32 Deluxe :: 4X250GB SATAII
    Need instant help? Try us on IRC -- #linuxforums on freenode

  2. #2
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Good work. A simpler way to accomplish this is to get the value directly off the stack like:

    Code:
    	movl	8(%esp), %edi
    Make mine Arch Linux

  3. #3
    Linux Guru smolloy's Avatar
    Join Date
    Apr 2005
    Location
    CA, but from N.Ireland
    Posts
    2,413
    Cheers Gerard. Here's an updated version of the asm file. Incredibly, the executable fits into less than 200 bytes!

    I have to admit that even though I can't think of a single good reason to use assembly, I am having an awful lot of fun learning it!

    Code:
    global _start
    
    section .data
            term    db      " ", 10
            length  equ     $-term
    
    section .text
    
    _start:
            mov     edi, [esp+8]    ; Grab the input string off the stack
    
            xor     ecx, ecx        ; ECX = 0
            not     ecx             ; ECX = -1 (signed)
            xor     al, al          ; AL = 0
            cld                     ; Set direction of scan
            repne   scasb           ; Find string location that equals AL
            not     ecx             ; ECX = abs(ECX) -1
            dec     ecx             ; ECX -= 1
    
            mov     edx,ecx         ; string length
            mov     eax, 4          ; write to file
            mov     ebx, 1          ; STDOUT handle
            mov     ecx, [esp+8]    ; the string
            int     80h             ; execute the syscall
    
            mov     eax, 4          ; write to file
            mov     ebx, 1          ; STDOUT handle
            mov     ecx, term
            mov     edx, length
            int     80h
    
            mov     eax, 1          ; terminate process
            xor     ebx, ebx        ; send 0 as 'exit code'
            int     80h             ; execute the syscall
    Registered Linux user #388328 || Registered LFS user #15880
    AMD 64 X2 4600+ :: 2X1GB DDR2 800 :: GeForce 9400 GT 512MB :: ASUS M2N32 Deluxe :: 4X250GB SATAII
    Need instant help? Try us on IRC -- #linuxforums on freenode

  4. #4
    Linux Enthusiast Bemk's Avatar
    Join Date
    Sep 2008
    Location
    Oosterhout-NB, Netherlands
    Posts
    522
    I am trying to learn assembler as well, just to get to know the insides of the PC.

    I'm not even close to where you are, for I'm still trying to figure out what the basic keywords are. I do like what you've done. It helps me getting to know assembler a bit better.

  5. #5
    Linux Newbie egan's Avatar
    Join Date
    Feb 2009
    Location
    Mountain View, CA
    Posts
    132
    Do you have any tutorials to recommend. I have tried learning assembly before, but I have had a hard time finding anything from which to learn.

  6. #6
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Make mine Arch Linux

  7. #7
    Linux Enthusiast Bemk's Avatar
    Join Date
    Sep 2008
    Location
    Oosterhout-NB, Netherlands
    Posts
    522
    This is what I'm reading:

    The Art of Assembly Language Programming

  8. #8
    Trusted Penguin elija's Avatar
    Join Date
    Jul 2004
    Location
    Either at home or at work or down the pub
    Posts
    2,301
    Oh man that brings back memories. I used to program my Atari STe in Assembly.

    I'm off to wallow in a nice warm pool of 80's nostalgia.
    If we hit that bullseye, the rest of the dominoes will fall like a house of cards. Checkmate! (Zapp Brannigan)


    My new blog. It's probably not as good as I think it is.

  9. #9
    Linux Guru smolloy's Avatar
    Join Date
    Apr 2005
    Location
    CA, but from N.Ireland
    Posts
    2,413
    Here is the one I have found most useful.

    PC Assembly Language

    I'm slowly working my way through it, and have found that my understanding has come on in leaps and bounds since I started. He provides a zip file of all the code discussed, which is very useful for using as a starting point for your own code.
    Registered Linux user #388328 || Registered LFS user #15880
    AMD 64 X2 4600+ :: 2X1GB DDR2 800 :: GeForce 9400 GT 512MB :: ASUS M2N32 Deluxe :: 4X250GB SATAII
    Need instant help? Try us on IRC -- #linuxforums on freenode

  10. #10
    Linux Guru smolloy's Avatar
    Join Date
    Apr 2005
    Location
    CA, but from N.Ireland
    Posts
    2,413
    Here is the latest version of my code. Now it returns multiple input arguments, and is starting to look very much like an assembly version of bash "echo".
    Code:
    global _start
    
    section .data
            space   db      " "
            term    db      " ", 10
            tlength equ     $-term
    
    section .text
    
    %define EXIT_OK 0
    %define FWRITE 4
    %define STDOUT 1
    %define ENDPROC 1
    
    _start:
            pop     edi             ; Number of input args
            pop     edi             ; The name of the executable.  Not used.
    
    while:
            pop     edi             ; Get the string off the stack
            test    edi, edi        ; edi AND edi.  edi=NULL is the only state resulting in 0
            jz      endwhile        ; Test for the end
            push edi                ; Store it back on the stack to prevent corruption
    
            xor     ecx, ecx        ; ECX = 0
            not     ecx             ; ECX = -1 (signed)
            xor     al, al          ; AL = 0
            cld                     ; Set direction of scan
            repne   scasb           ; Find string location that equals AL
            not     ecx             ; ECX = abs(ECX) -1
            dec     ecx             ; ECX -= 1
    
            mov     edx,ecx         ; string length
            mov     eax, FWRITE     ; write to file
            mov     ebx, STDOUT     ; STDOUT handle
            mov     ecx, [esp]      ; the string
            int     80h             ; execute the syscall
    
            mov     edx, 1          ; Now print a space to separate input args
            mov     eax, FWRITE     ; write to file
            mov     ebx, STDOUT     ; STDOUT handle
            mov     ecx, space
            int     80h
    
            pop edi                 ; Dump the data
    
            jmp     while           ; Loop
    endwhile:
    
            mov     eax, FWRITE     ; write to file
            mov     ebx, STDOUT     ; STDOUT handle
            mov     ecx, term
            mov     edx, tlength
            int     80h
    
            mov     eax, ENDPROC    ; terminate process
            xor     ebx, ebx        ; send 0 as 'exit code'
            int     80h             ; execute the syscall
    Registered Linux user #388328 || Registered LFS user #15880
    AMD 64 X2 4600+ :: 2X1GB DDR2 800 :: GeForce 9400 GT 512MB :: ASUS M2N32 Deluxe :: 4X250GB SATAII
    Need instant help? Try us on IRC -- #linuxforums on freenode

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...