Lab 3: Solutions

There is a lot of whitespace between the solutions. Use the menu to jump to the solution of interest.

Lab 3.1 Solutions

ASM If Condition
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
; ASM Simple IF statement of this if block
;
; // Value to try to square
; int value = 8192;
;
; // If successful, set the value
; if (can_square)
;     value = value * value;
;
; // Print the value, either original or modified
; printf(value);
;

; include directives
global asm_main
%include "../lib/asm_io.inc"

segment .data
    ; DX directives (read only, static data)

segment .bss
    ; RESX directives (writable data)

segment .text
asm_main:                   ; entry point (called from driver.c)
    ; instructions

    enter 0,0               ; Initialize register EBP
    pusha                   ; Push register contents to the stack

    ; Starting values
    mov     ecx,  8192      ; Result OK.         Print ---> 67108864
  ; mov     ecx,  65536     ; Overflow detected. Print ---> 65536
    mov     eax,  ecx       ; Initialize EAX

    ; Try to square the value. Then, evaluate for OF flag
    mul     eax             ; value = value * value

    ; Verify flags with registers
    dump_regs 0

; Here, we have to check for the overflow flag. This is the only way to know
; if the value can be squared. We have to look at it AFTER the operation.
;
;   if (!can_square)
;      EAX = ECX;           ; put original value in EAX (can't square it)
;
    jno      end            ; no overflow, value is ok. Go to end
    mov     eax,    ecx     ; overflow happened, move ECX back to EAX to print

end:

    ; Print the value in EAX. It will be the square or the original
    call    print_int        ; print the value in EAX
    call    print_nl         ; print in new line

    popa                     ; Restore register data from the stack
    mov eax, 0               ; flush EAX of data
    leave                    ; restore the stack
    ret                      ; Return from main back into C library wrapper

Scroll down for next solution:































Lab 3.2 Solutions

Determines if Number is Even or Odd
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
; IF/Else Block
;
; Evalutes a number for even or odd.
; Print 0 if the number is even
; Print 1 if the number is odd.
;
; include directives
global asm_main
%include "../lib/asm_io.inc"

segment .data
    ; DX directives (read only, static data)

segment .bss
    ; RESX directives (writable data)

segment .text
asm_main:                   ; entry point (called from driver.c)
    ; instructions

    enter 0,0               ; Initialize register EBP
    pusha                   ; Push register contents to the stack

    ; Starting values
    mov     eax,  10        ; Even case
  ; mov     eax,  9         ; Odd case
    mov     edx,  0          ; Initialize EDX for division

    ; Divide the number and check for remainder
    mov     ecx,  2         ; the divisor
    div     ecx             ; divide and check EDX for a remainder

    ; evaluate registers for EDX
    dump_regs 0

    cmp     edx,  0         ; compare, and then jump
    jnz     odd_number      ; JNZ: Jump if not zero. EDX has a remainder

    ; Our number is even (EDX was 0)
    mov     eax,  0         ; --> 0 means even number
    jmp     print           ; jump over the else block to end it

    ;The number is odd
odd_number:
    mov     eax, 1           ; value = 1

print:
    ; print the contents of AEX: 0 or 1
    call    print_int        ; print eax
    call    print_nl         ; print in new line
    ;
    popa                     ; Restore register data from the stack
    mov eax, 0               ; flush EAX of data
    leave                    ; restore the stack
    ret                      ; Return from main back into C library wrapper

Scroll down for next solution:































Lab 3.3 Solutions

While loop implementation
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
; Loop until a number becomes negative
;
; An implementation of:
; while (number >= 0)
;

; include directives
global asm_main
%include "../lib/asm_io.inc"

segment .data
    ; DX directives (read only, static data)

segment .bss
    ; RESX directives (writable data)

segment .text
asm_main:                   ; entry point (called from driver.c)
    ; instructions

    enter 0,0               ; Initialize register EBP
    pusha                   ; Push register contents to the stack
    ;
    mov     eax,  999999    ; Starting number

    ; debug
    dump_regs  0;           ; current state of registers

subtract:
    sub      eax, 111110        ; subtract until we get to a negative value
    js       negative_number    ; end loop if SF flag is set
    ; Print current results
    call     print_int      ; print eax
    call     print_nl       ; new line
    jmp      subtract       ; continue loop

negative_number:
    dump_regs  0;            ; verify SF flag

    ; end
    ;
    popa                     ; Restore register data from the stack
    mov eax, 0               ; flush EAX of data
    leave                    ; restore the stack
    ret                      ; Return from main back into C library wrapper

Scroll down for next solution:































Lab 3.4 Solutions

ASM Factorial Implementation
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
; Prints the result of a factorial.
; Generates an error on overflow
;

; include directives
global asm_main
%include "../lib/asm_io.inc"

segment .data
    ; DX directives (read only, static data)

segment .bss
    ; RESX directives (writable data)

segment .text
asm_main:                    ; entry point (called from driver.c)
    ; instructions

    enter 0,0                ; Initialize register EBP
    pusha                    ; Push register contents to the stack
    ;

    mov    ecx,  1          ; ecx is i
    mov    ebx,  5          ; factorial to calculates 5! = 120
  ; mov    ebx,  18         ; Test error handling. Causes overflow
    mov    eax,  1          ; eax is factorial result

; Simple "for" loop to calculate the factorial of a number
factorial:
    cmp    ecx,  ebx        ; compare i and factorial
    jg     print            ; if (i > factorial) exit loop
    mul    ecx              ; result = result * i;
    jo     overflow         ; error on overflow flag
    inc    ecx              ; i++
    jmp    factorial        ; process next number

; Encountered an overflow. Handle error
overflow:
    mov    eax,  ecx        ; Move counter to AEX
    call   print_int        ; print counter (the factorial that caused the OF)
    call   print_nl         ; print nl
    mov    eax,  -1         ; set to invalid result

print:
    call print_int          ; print factorial
    call print_nl           ; print new line

    ; program continues
    ;
    popa                     ; Restore register data from the stack
    mov eax, 0               ; flush EAX of data
    leave                    ; restore the stack
    ret                      ; Return from main back into C library wrapper