Work / Virtual Machine / Example Source Code

2011-02-19 23:20:19

Prime Number Determination

Determining if a number is a Prime:

C Code:

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
61
62
63
void main(char* args)
{
    args = collapse_whitespace(args);
    uint argsLen = strlen(args);
    char* spaceOfs = strstr(args, findPrimes_space);
    if(!spaceOfs)
    {
        std.cout(findPrimes_usage);
        return;
    }
    char findPrimes_arg1[32] = {0};
    uint arg1len = spaceOfs - args;
    strncpy(findPrimes_arg2, args, arg1len);
    ++spaceOfs;
    char findPrimes_arg2[32] = {0};
    uint charOfs = spaceOfs - args;
    uint arg2len = argsLen - charOfs;
    strncpy(findPrimes_arg2, spaceOfs, arg2len);
    uint arg1int = StrToInt(findPrimes_arg1);
    uint arg2int = StrToInt(findPrimes_arg2);
    std::cout << findPrimes_msg0;
    std::cout << findPrimes_arg1;
    std::cout << findPrimes_msg1;
    std::cout << findPrimes_arg2;
    std::cout << findPrimes_nl;
    findPrimes(arg1int, arg2int);
}

void findPrimes3(uint start, uint end)
{
    if(start > end) return;
    uint i = start;
    while(i <= end)
    {
        if(IsPrime(i))
        {
            std::cout << IntToStr(i) << "\n";
        }
        i++;
        if(i == 0) break;
    }
 }

bool IsPrime(uint number)
{  
    if(number < 2)
        return false;
    if(number == 2)
        return true;
    if(number % 2 == 0)
        return false;
    uint divisor = 2;
    uint max = sqrt((double)number);
    while(divisor <= max)
    {
        if(number % divisor == 0)
        {
            return false;
        }
        ++divisor;
    }
    return true;
}

VM ASM Code:

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
; $Header: $

stacksize 256

segment .data            
    findPrimes_com      db      ", ", 0
    findPrimes_msg0     db      "Finding Prime Numbers between ", 0
    findPrimes_msg1     db      " and ", 0
    findPrimes_nl       db      "\n", 0
    findPrimes_tab      db      "\t", 0
    findPrimes_space    db      " ", 0
    findPrimes_arg1     resb    32
    findPrimes_arg2     resb    32
    findPrimes_usage    db      "parameters:   (max: 4294967295)", 0

segment .text
    import  std.cout
    import  std.strlen
    import  std.strstr
    import  std.strncpy
    import  math.sqrt

    import  strlib.IntToStr
    import  strlib.StrToInt
    export  main

; -------------------------------------
; void main(char* args)
;
; lv0 = args
; lv1 = spaceOfs
; lv2 = argsLen
; lv3 = charOfs
; lv4 = arg2len
; lv5 = arg1len
; lv6 = arg1int
; lv7 = arg2int

main:
    nvar    0, args
    nvar    1, spaceOfs
    nvar    2, argsLen
    nvar    3, charOfs
    nvar    4, arg2len
    nvar    5, arg1len
    nvar    6, arg1int
    nvar    7, arg2int

    entf    8, 1    ; copy argument string into lv0 (args)

    push    args
    farc    std.strlen
    popr    argsLen, 1

    push    args
    pshd    findPrimes_space
    farc    std.strstr
    popr    spaceOfs, 2

    jz      spaceOfs, .invalidArgs  ; if(!args.contain(' '))

    mov     arg1len, spaceOfs      
    sub     arg1len, args          

    pshd    findPrimes_arg1    
    push    args               
    push    arg1len                
    farc    std.strncpy
    popn    3

    inc     spaceOfs                   
    mov     charOfs, spaceOfs              
    sub     charOfs, args          

    mov     arg2len, argsLen               
    sub     arg2len, charOfs               

    pshd    findPrimes_arg2    
    push    spaceOfs           
    push    arg2len                
    farc    std.strncpy
    popn    3

    pshd    findPrimes_arg1    
    farc    strlib.StrToInt         ; call StrToInt(findPrimes_arg1);
    popr    arg1int, 1          ; pop result into lv6 (arg1int)

    pshd    findPrimes_arg2    
    farc    strlib.StrToInt         ; call StrToInt(findPrimes_arg1);
    popr    arg2int, 1          ; pop result into lv7 (arg2int)

    pshd    findPrimes_msg0    
    farc    std.cout            ; std.cout(findPrimes_msg0);
    popn    1                   ; pop pushed pointer

    pshd    findPrimes_arg1    
    farc    std.cout            ; std.cout(findPrimes_arg1);
    popn    1                   ; pop pushed pointer

    pshd    findPrimes_msg1    
    farc    std.cout            ; std.cout(findPrimes_msg1);
    popn    1                   ; pop pushed pointer

    pshd    findPrimes_arg2    
    farc    std.cout            ; std.cout(findPrimes_arg2);
    popn    1                   ; pop pushed pointer

    pshd    findPrimes_nl      
    farc    std.cout            ; std.cout(findPrimes_nl);
    popn    1                   ; pop pushed pointer

    psh2    arg1int, arg2int
    call    findPrimes3
    popn    2

    lrtn

.invalidArgs:
    pshd    findPrimes_usage   
    farc    std.cout            ; std.cout(findPrimes_usage);
    popn    1                   ; pop pushed pointer
    lrtn

; -------------------------------------
; void findPrimes3(uint start, uint end)

findPrimes3:
    nvar    0,      start
    nvar    1,      end
    nvar    2,      i
    nvar    3,      isPrime

    entf    4,      2

    jg      start,  end,    .endLoop

    mov     i,      start
.loop:
    jg      i,      end,    .endLoop

    push    i
    call    IsPrime
    popr,   isPrime,    1

    jz      isPrime,    .notPrime

    push    i
    pshi    10             
    farc    strlib.IntToStr    
    farc    std.cout       
    popn    3              

    pshd    findPrimes_nl
    farc    std.cout
    popn    1
.notPrime:
    inc     i
    jz      i,      .endLoop
    jmp     .loop
.endLoop:
    lrtn

; -------------------------------------
; bool IsPrime(uint number)
;
; lv0 = number
; lv1 = divisor
; lv2 = max
; lv3 = number % divisor
; lv4 = value of 2
; lv5 = number % 2

IsPrime:
    nvar    0,          number
    nvar    1,          divisor
    nvar    2,          max
    nvar    3,          nmodd
    nvar    4,          two
    nvar    5,          nmod2

    entf    6,          1

    movi    two,        2
    jl      number,     two,        .notPrime
    jcmp    number,     two,        .isPrime

    mov     nmod2,      number
    mod     nmod2,      two
    jz      nmod2,      .notPrime

    mov divisor,    two

    push    number
    farc    math.sqrt
    popr    max,        1
    ftoi    max,        max

.loop:
    jg      divisor,    max,        .endLoop

    mov     nmodd,      number
    mod     nmodd,      divisor
    jz      nmodd,      .notPrime

    inc     divisor

    jmp     .loop
.endLoop:

.isPrime:
    lrti    1
.notPrime:
    lrti    0