2014-12-17 10 views
1

에 두 숫자를 비교하여 나는 다음과 같은 어셈블리 코드가 있습니다는 인텔 x86 어셈블리 (NASM)

%include 'rw32.inc' 

[segment .data use32] 

a dd 2.0 
b dd 1.0 
[segment .code use32] 

prologue    ; macro -- inicialization 
    fld dword [a] 
    fld dword [b] 
    fcom 
    jc greater 
    jmp less 
greater: 
    fxch 
less: 
    call WriteDouble 
    call WriteNewLine 
    epilogue    ; macro -- termination 

rw32.inc이 프로그램 초기화 및 종료 등의 기능을 포함 유틸리티 라이브러리입니다. WriteDouble - 화면에 st0을 인쇄합니다. WriteNewLine - 줄 바꿈을 삽입하기 만하면됩니다.

그리고이 숫자 'a'와 'b'를 비교하여 더 큰 것을 인쇄하고 싶습니다. 내 논리는 다음과 같습니다. 두 숫자를 스택으로 가져옵니다. fcom으로 플래그를 설정합니다. 캐리 플래그가 1이면 번호 'a'가 더 큽니다. 따라서 'b'로 전환해야하므로 스택 맨 위에 있습니다. 그렇지 않으면 'b'가 더 크고 결과 만 출력됩니다.

그러나 프로그램이 '큰'레이블로 점프하지 않는 것 같습니다. 어떻게 해결할 수 있습니까? 감사합니다.

+1

https://courses.engr.illinois.edu/ece390/books/artofasm/CH14/CH14-5.html#HEADING5-5 읽기 : '일반적으로 대부분의 프로그램은 비교 직후에 조건 코드 비트를 테스트합니다. 아쉽게도 FPU 조건 코드를 기반으로 분기하는 조건부 점프 명령은 없습니다. 대신 fstsw 명령을 사용하여 부동 소수점 상태 레지스터를 복사 할 수 있습니다 ... ' –

+0

예! 나는 그런 지시가 있다고 생각했지만, 나는 그 이름을 기억할 수 없었다. 하지만 이것은 fpu 상태 레지스터를 예를 들어 AX (fstsw AX). 하지만 AX의 내용을 FLAGS 레지스터에로드 할 수있어서 'jc'명령어를 사용할 수 있습니까? – user1967718

+0

전체 단락을 읽으십시오. –

답변

1

FPU 수학은 carry와 zero와 같은 CPU 플래그를 절대 사용하지 않아야합니다!

그래서 fcomp 명령 후에 CPU 플래그 레지스터에 FPU에서 플래그를 복사 캐리와 같은 제로 플래그를 확인보다 :

fld qword ptr [a] 
fcomp qword ptr [b] 
wait     ;wait FPU 
fstsw ax    ;copy FPU flags to ax 
sahf     ;copy ax to CPU flags 
jbe LessOrEqu  ;do less or equal 
... 
2

인텔 좋은 사람들이 우리에게 fcomi(p) 준 이유 :

을 레지스터 ST (0) 및 ST (i)의 내용을 순서없이 비교하고 결과에 따라 EFLAGS 레지스터에 상태 플래그 ZF, PF 및 CF를 설정합니다.

fstsw ax \ sahf 메서드는 고대이며 모든 "비 고대"CPU (일부 오래된 x64 프로세서는 sahf이 아님)에서 작동하지 않습니다. wait의 사용은 공룡이 지구를 배회하고 FPU가 코 프로세서 였을 당시의 고대 코드의 표시입니다.