I am still on my journey into the world of assembly, and feel that I am becoming more comfortable with it, however; there are somethings I am still struggling with. Below I have posted my code, and have inline comments with it. These comments represent my understanding of the particular line, but in some cases I have question marks. These represent the areas that I am most uncomfortable or unsure about how to tackle. I would greatly appreciate if someone, in a non 'fancy-pants' manner could help me understand what these question mark lines mean. Thank You

; file: prime.asm
; This program calculates prime numbers, and after each line I try my best to explain my understanding of the code
; To create executable:
; nasm -f elf prime_my_explanation.asm
; gcc -o prime_my_explanation prime_my_explanation.o driver.c asm_io.o
; Works like the following C program: ; So the author says
; #include <stdio.h>
;int main()
;  unsigned guess;          /* current guess for prime      */
;  unsigned factor;         /* possible factor of guess     */
;  unsigned limit;          /* find primes up to this value */
;  printf("Find primes up to: ");
;  scanf("%u", &limit);
;  printf("2\n");    /* treat first two primes as special case */
;  printf("3\n");
;  guess = 5;        /* initial guess */
;  while ( guess <= limit ) {
;    /* look for a factor of guess */
;    factor = 3;
;    while ( factor*factor < guess && guess % factor != 0 )
;      factor += 2;
;    if ( guess % factor != 0 )
;      printf("%d\n", guess);
;    guess += 2;    /* only look at odd numbers */
;  }
;  return 0;

%include ""

segment .data
Message         db      "Find primes up to: ", 0    ;will be used to output the string 'Find primes up to: '

segment .bss        ;this section will be used to declare uninitialized data
Limit           resd    1               ; The variable Limit will be used as the upper bound of the loop
Guess           resd    1               ; This variable will serve as the current guess of prime, at the specific time within' the loop

segment .text       ;this section is where you put all the fancy-pants code
        global  asm_main        ;this serves as the main method of this specific assemebly program
asm_main:               ;
        enter   0,0               ; may the electric wizardry of the assembly program begin

        mov     eax,  Message   ;mov 'Find primes up to: ' into the EAX register
        call    print_string        ;call print_string, which will output 'Find primes up to: '

        call    read_int             ; call read_int, which will read in an integer input from the user, and put it in the EAX register
        mov     [Limit], eax        ; place the value specified by the user in the Limit variable

        mov     eax, 2               ; move the value of 2 into the EAX register
        call    print_int       ;print out the integer value in the EAX register, in this case 2
        call    print_nl        ;call the print_nl method, which will print a newline character
        mov     eax, 3               ; move the value of 3 into the EAX register
        call    print_int       ;print the value within' the EAX register, in this case 3
        call    print_nl        ;printout a new line

        mov     dword [Guess], 5     ; ? define Guess as a 32bit unsigned integer, and within' that value store the number we want to find out if is prime (5)

while_limit:                         ; while our Guess <= Limit
        mov     eax,[Guess] ;move the value of Guess (5) into the EAX register
        cmp     eax, [Limit]        ;compare the value of EAX and Limit
        jnbe    end_while_limit      ; jump if not below or equal to (!<=) ? does this mean if eax <= Limit or eax >= Limit?

        mov     ebx, 3               ; 3 will serve as the factor, so store it within the EBX register
        mov     eax,ebx ;move the value of EBX (3) into the EAX register
        mul     eax                  ; EAX = EAX * EAX (9) ?
        jo      end_while_factor     ; If the Overflow flag is set then goto end_while_factor
        cmp     eax, [Guess]        ;now compare the value of Guess and EAX
        jnb     end_while_factor     ; if !(9 < guess) ?
        mov     eax,[Guess] ; move the value of Guess (5) into the EAX register
        mov     edx,0           ; move 0 into the EDX register
        div     ebx                  ; edx = edx:eax % ebx ???
        cmp     edx, 0      ; compare the value of EDX (the remainder of EAX % EBX)
        je      end_while_factor     ; if !(guess % factor != 0) ?

        add     ebx,2                ; the value currently in the EBX register (3) is added to two
        jmp     while_factor    ;jump to while_factor continuing the while structure
end_while_factor:       ; after the looping structure completes do the following
        je      end_if               ; if !(guess % factor != 0) ?
        mov     eax,[Guess]          ; move our guess to the EAX register
        call    print_int       ; output the value of the EAX register
        call    print_nl        ; output a new line
end_if:     ;end the if...else structure
        mov     eax,[Guess] ;put the guess (5) into the EAX register
        add     eax, 2  ; eax = eax (guess) + 2
        mov     [Guess], eax         ; move the value of eax (5+2 = 7) into the variable Guess
        jmp     while_limit ;jump to the while_limit, and repeat if condition is true

        mov     eax, 0            ; return back to C

Thank you, once again

Recommended Answers

All 5 Replies

Long time since I wrote my last asm code, but I'll try to answer your questions:

69. mov dword [Guess], 5 states that a 5 will be moved to position pointed by Guess and value will occupy a double word length (32 bits). This is equivalent to 'guess = 5' in C, though in C you move always 32 bits: you don't just move 16 bits as in

mov word [guess], 5

79. The comment is right, it's eax * eax = 9
82. Line 81 compares eax and the value 'pointed' by 'Guess', this updates the status registers, so in #82 'jump if not below' jnb will jump if factor*factor >= Guess. This jump will avoid adding 2 in line 89 (Think that the 1st condition of line 28 is failing so it jumps to line 30, whose equivalent is line 91)
85 64-bit contents of EDX-EAX are divided by the operand (ebx), leaving a 32-bit quotient in eax and a 32-bit remainder in edx.
87 if edx was equal to 0 (#86) it will jump to end_while_factor, because now the 2nd condition (see line 28) is failing and addition in line #89 needs to be omitted.
92 'je' is a mnemonic for 'jump if equal' in the last 'cmp' executed.
commented: Thank you for the help. +0

@xrj, Thank you for the help. However, I am still trying to understand the way in which the compare operator works for example
cmp eax, 0
and then say I wanted to use
je some_block_of_code
how does the compare operator work.
Does it work left to right or right to left?

Let's say it works from left to right.
If eax contains a 5, then:
cmp eax, 6 ; eax < 6
jb label ; will jump to label

commented: Exactly what I needed to see. Thank you again =D +0

Thank you, I was just unsure because on my journey so far, I've noticed assembly likes working from right to left.

However, I am still trying to understand the way in which the compare operator works for example
cmp eax, 0

I realise this is solved, but just to clarify, with je the order in which the operands are specified doesn't matter; both of these are valid:

cmp eax, 0
cmp 0, eax

because eax = 0 and 0 = eax. Getting things in the right order only matters when you're dealing with >=, <=, > and <.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.