Programming in Assembly Language 
       After a long break I have started programming in pure assembly language again. My recent assembly experiences are to use short inline assembly in C/C++ code or looking at disassembly code during debugging. I have developed a little program to find out if an integer is a prime number or not. 
Platforms and necessary tools 
     The source code is written with AT&T syntax which is most common in *nix world and uses gas (GNU assembler) on Linux. Intel syntax is used for MASM, TASM and NASM and most common in DOS and Windows. Intel syntax can also be compiled with gas-2.9.1. Have a look at gas manual. 
 
You can have look at differences and similarities in AT&T and Intel syntax.
 
Following is the complete source code of my tiny program in prime.s file:
 
# Assembly source code to find out whether a number is prime or not
# hash sign (#) is used for comments in the source code
 
#next section is for data-variables,consts etc.
.section .data
msg_not_prime:
      .ascii      "Not a prime number\n"
      len =. - msg_not_prime
msg_prime:
      .ascii      "A prime number\n"
      len_prime = . - msg_prime
      
.section .text
 
      .equ      ST_ARGC_IN_FUNC, 8
      .equ      ST_NUMBER_IN_FUNC, 16
      .equ      ST_NUMBER, 8
      
.globl _start      #entry point - define something like C main()
 
_start:
      #Load the number from command line args
      call      args_to_int
      addl      $4, %esp # Free the stack allocated for the adress of 
                   # instruction after return
      #push the value in the stack, call prime function
      #and it's the parameter
      pushl      %eax
      call      prime        # Call a function
      addl      $4, %esp 
      
      cmpl      $1, %ebx  # Check the value in ebx; 1 for prime
      je      .is_prime
 
      movl      $len, %edx
      movl      $msg_not_prime, %ecx
      movl      $1, %ebx
      movl      $4, %eax
      int      $0x80
      jmp      .exit
.is_prime:
      movl      $len_prime, %edx
      movl      $msg_prime, %ecx
      movl      $1, %ebx
      movl      $4, %eax
      int      $0x80
 
.exit:
      movl      $0, %ebx
      movl      $1, %eax
      int      $0x80
 
#function to copy integer arg to eax
.type args_to_int, @function
args_to_int:      
      pushl      %ebp
      movl      %esp, %ebp
      
      xorl      %eax, %eax
      xorl      %ebx, %ebx
      xorl      %ecx, %ecx
 
      # return address + saved ebp ;  number of args
      movl      ST_ARGC_IN_FUNC(%ebp), %ebx
      cmpl      $1, %ebx  #if number of args is 1
      jle      .exit_args
      movl      ST_NUMBER_IN_FUNC(%ebp), %ebx # first arg is prog name
      movl      $10, %edi
 
      movb      (%ebx), %cl
      cmpb      $'-', %cl
      jne      .digit
      incb      %dh
      incl      %ebx
 
.next_digit:
      mov      (%ebx), %cl
.digit:
      subb      $'0', %cl
      jb      .done
      cmpb      $9, %cl
      ja      .done
      mull      %edi
      addl      %ecx, %eax
      incb      %dl
      incl      %ebx
      jmp      .next_digit
 
.done:
      orb      %dh, %dh
      je      .exit_args
      negl      %eax
      
.exit_args:
      movl      %ebp, %esp
      popl      %ebp
      ret
      
# This function will store 1 in ebx if the number is prime
# otherwise, will store 0 (zero)
.type prime, @function
prime:
      pushl      %ebp
      movl      %esp, %ebp
 
      movl      $1, %ebx
      movl      8(%ebp), %eax
      cmpl      $3, %eax
      jle      .end_loop
      movl      $2, %ecx
 
.loop_start:
      movl      $1, %ebx
      cmpl      8(%ebp), %ecx
      je      .end_loop
      movl      $0, %ebx
      movl      8(%ebp), %eax
      movl      $0, %edx
      divl      %ecx
      cmpl      $0, %edx
      je      .end_loop
      incl      %ecx
      jmp      .loop_start
      
.end_loop:  
      movl      %ebp, %esp
      popl      %ebp
      ret
 
 
How to generate program file:
    
gas (GNU assembler) is used to compile the souce and ld is used to link the compiled object code to generated executable. Both of them reside in GNU Binutils. 
 
- Copy the      source to a file named prime.s
- Compile the      source
as  -o prime.o prime.s
- Link the      object file
ld -o prime prime.o
- Run the      executable
./prime 7
 
It should give the following output:
A Prime Number
 
References:
 
- For      everything to Program in assembly under Linux and Unix: http://www.linuxassembly.org/      
- Programming      from the Ground Up: http://savannah.nongnu.org/projects/pgubook/
- Art of Assembly.
 
 

 
 Posts
Posts
 
 
No comments:
Post a Comment