C 코드에 대한 Prime.Asm 예 도움말 :PC 어셈블리 언어 (폴 카터) - JO 그리고 JE
#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;
}
어셈블리 코드 (NASM) :
%include "asm_io.inc"
segment .data
Message db "Find primes up to: ", 0
segment .bss
Limit resd 1 ; find primes up to this limit
Guess resd 1 ; the current guess for prime
segment .text
global _asm_main
_asm_main:
enter 0,0 ; setup routine
pusha
mov eax, Message
call print_string
call read_int ; scanf("%u", & limit);
mov [Limit], eax
mov eax, 2 ; printf("2\n");
call print_int
call print_nl
mov eax, 3 ; printf("3\n");
call print_int
call print_nl
mov dword [Guess], 5 ; Guess = 5;
while_limit: ; while (Guess <= Limit)
mov eax,[Guess]
cmp eax, [Limit]
jnbe end_while_limit ; use jnbe since numbers are unsigned
mov ebx, 3 ; ebx is factor = 3;
while_factor:
mov eax,ebx
mul eax ; edx:eax = eax*eax
**jo end_while_factor ; if answer won't fit in eax alone**
cmp eax, [Guess]
jnb end_while_factor ; if !(factor*factor < guess)
mov eax,[Guess]
mov edx,0
div ebx ; edx = edx:eax % ebx
cmp edx, 0
je end_while_factor ; if !(guess % factor != 0)
add ebx,2 ; factor += 2;
jmp while_factor
end_while_factor:
**je end_if ; if !(guess % factor != 0)**
mov eax,[Guess] ; printf("%u\n")
call print_int
call print_nl
end_if:
mov eax,[Guess]
add eax, 2
mov [Guess], eax ; guess += 2
jmp while_limit
end_while_limit:
popa
mov eax, 0 ; return back to C
leave
ret
당신이 볼 수 있듯이, 내가 가진 ** 두 가지 지침이 표시되어 있습니다.
우선, MUL 명령어는 EAX * EAX를 곱하고 그 값을 EAX에 맞게 너무 큰 경우 EDX : EAX에 저장합니다. 맞습니까? 그런 다음 프로그램이 오버플로를 확인합니다. 값이 너무 커서 EAX에 맞지 않으면 시스템은 오버플로를 감지하고 OF = 1로 설정합니까? 왜? 필요한 경우 EAX & EDX에 값을 저장하지 않으시겠습니까?
둘째, JE 명령입니다. 설명문은 if! (추측 % factor! = 0)입니다. ! (요인 * 요소 < 0) 경우 점프가 있기 때문에 오버 플로우 검사 만들어진, 또는 어떤 경우
cmp edx,0
je end_while_factor
그러나 다음 프로그램에서이 점프 할 때
그게 좋아? 괜찮습니까? 비교할 값은 무엇입니까? 그냥 ZF를 확인합니까? 그러나 이전에 다른 이유로 변경되지 않았습니다 (다른 명령).
미리 도움을 주셔서 감사합니다.
답변 해 주셔서 감사합니다. OF의 현재 상황은 명확합니다. JE 정보 ... 이전에는 명령 : cmp eax, [Limit]가 실행되었습니다. eax = [Limit]이면 JMP가 작성되지 않고 while 루프가 시작되므로 cmp 때문에 ZF = 1입니다. 오버 플로우가 발생하여 프로그램이 end_while_factor로 점프하면 ZF가 1로 남아 있기 때문에 번호가 인쇄되지 않습니다. –
Erm, 아니요, 그 비교는 end_while_limit로 점프합니다. end_while_factor로 점프하는 장소가 여러 곳 있습니다. 이것은 단지 버그 코드입니다. –
좋습니다! 도와 줘서 고마워! –