Laboratory 11 - Examples

Multi-modul programming (asm+asm)

Example

A program to compute the factorial of a number will be written. "Main program" is main.asm, and factorial function is defined in modul.asm. To be able to assemble and to edit links we need the command line. Below it is presented the assembly process, link editing which results in an executable program:

  • Given the director asc on the disk D, in this director are the program's sources (main.asm și modul.asm);
  • It is necesarly that in the director asc to copy nasm.exe and alink.exe (programs located in the director nasm from the tools);
  • For an easier way of browsing in the command line to the location on the disk where sources are we can use Total Commander, we browse visually to the director asc and launch the command line (see the bellow image)

  • if you don't want to use Total Commander, launch cmd.exe and with the following command lines browse to the director asc
> d:
> cd  asc
  • whatever the choice the result should be the one from the following image

  • command dir shows the content of the current director, it is checked if the current director contains the sources .asm and the programs alink.exe and nasm.exe (see the bellow image)

  • the two sources are aseambled with the command lines
> nasm -fobj modul.asm
> nasm -fobj main.asm
  • the result is the one from the bellow image, two files .obj

  • using alink.exe (link editor), from the two files .obj will be created the executable, the resulted filename .exe is the same with the ones of the first file .obj given as a parameter to the link editor, in this case main. The prgram can be run, in this case main.exe writes to the console 6! = 720 (see the bellow image)

  • to debug, the code from ollydbg, File->Open and the executable file opens, in this case main.exe

Sources

Example 1:
  1. lab11_1.asm
Examplelul 2:
  1. lab11_proc_main.asm
  2. factorial.asm
Example 3:
  1. main.asm
  2. modul.asm

Recursive factorial - Example proposed by student Molnar Radu, group 215, 2017-2018

bits 32 ; assembling for the 32 bits architecture
; declare the EntryPoint (a label defining the very first instruction of the program)
global start        

; declare external functions needed by our program
extern exit,printf,scanf; add the external functions that we need
import exit msvcrt.dll    
import printf msvcrt.dll
import scanf msvcrt.dll

; our data is declared here (the variables needed by our program)
segment data use32 class=data
    ; ...
    text db "give n=",0
    final db "n!=%d",0
    format db "%d",0
    a resd 1                  ; the variable will store the number n read from the console
    

; our code starts here
segment code use32 class=code
    factor:
        ;to implement the problem recursively we need to break it in cases
        ;to compute the factorial we have two cases:
        ;n!=n*(n-1)!       - current iteration
        ;0!=1                  - stop condition
        ;the subprogram will repeat itsealf until ecx=0 when we make eax = 1 and return to the previous step
        mov ecx, [esp+4] ;move in ecx the number of steps that need to be done
        jecxz sf ;if ecx is 0 we jump to the label sf to start computing the factorial
        ;if we pass the comparison with 0 the we are at the first case of recursivity 
        ;the formula is n!=n*(n-1)!
        dec ecx; decrease ecx to call again the function for the next step
        push ecx;  push on the stack the current value of n 
        call factor; call the function with the current parameter with the value from the stack
        mul dword [esp+8]; multiply by the value of the current step
        add esp,4; free the stack to go back to the previous step
        jmp return; jump to the label return to step out from the subprogram
        
   sf:
        mov eax,1;because our recursivity has two cases we reached the case when ecx is 0 and return 1 – the stop condition 
        ;0!=1
        return:
        ret ;we go back to the previous step or to the main program
   start:
        ; ...
        ;writting the message
        push dword text
        call [printf]
        add esp,4

        ;read n from the console
        push dword a
        push dword format
        call [scanf]
        add esp,4*2 
        
        mov ecx,0
        mov eax,0;prepare the registers for the call
        push dword [a] ;save on the stack n
        call factor ;call the function

        ;writting the result
        push eax
        push final
        call [printf]
        ; exit(0)
        push dword 0; push the parameter for exit onto the stack
        call [exit]; call exit to terminate the program