यह सब Intel 64 and IA-32 Architectures Software Developer's Manuals के वॉल्यूम 2 से आ रहा है।
FCOMI
सेट झंडे कि CMP
करता है की केवल कुछ। आपके कोड में %st(0) == 9
और %st(1) == 10
है। (चूंकि यह एक स्टैक है जिसे वे लोड कर रहे हैं), वॉल्यूम 2 ए में पेज 3-348 पर तालिका का जिक्र करते हुए आप देख सकते हैं कि यह "एसटी 0 < एसटी (i)" है, इसलिए यह जेडएफ और पीएफ और सेट को साफ़ करेगा सीएफ़ इस बीच पीजी पर। 3-544 वॉल्यूम 2 ए आप पढ़ सकते हैं कि JG
का अर्थ है "अधिक से अधिक कूदें (ZF = 0 और SF = OF)"। दूसरे शब्दों में यह साइन, ओवरफ्लो और शून्य झंडे का परीक्षण कर रहा है, लेकिन FCOMI
साइन या ओवरफ़्लो सेट नहीं करता है!
आप किन स्थितियों पर कूदना चाहते हैं, इस पर निर्भर करते हुए, आपको संभावित तुलना परिणामों को देखना चाहिए और तय करना चाहिए कि आप कब कूदना चाहते हैं।
+--------------------+---+---+---+
| Comparison results | Z | P | C |
+--------------------+---+---+---+
| ST0 > ST(i) | 0 | 0 | 0 |
| ST0 < ST(i) | 0 | 0 | 1 |
| ST0 = ST(i) | 1 | 0 | 0 |
+--------------------+---+---+---+
मैं यह आसान यह पता लगाने की बनाने के लिए इस छोटी सी मेज कर दिया है:
+--------------+---+---+-----+------------------------------------+
| Test | Z | C | Jcc | Notes |
+--------------+---+---+-----+------------------------------------+
| ST0 < ST(i) | X | 1 | JB | ZF will never be set when CF = 1 |
| ST0 <= ST(i) | 1 | 1 | JBE | Either ZF or CF is ok |
| ST0 == ST(i) | 1 | X | JE | CF will never be set in this case |
| ST0 != ST(i) | 0 | X | JNE | |
| ST0 >= ST(i) | X | 0 | JAE | As long as CF is clear we are good |
| ST0 > ST(i) | 0 | 0 | JA | Both CF and ZF must be clear |
+--------------+---+---+-----+------------------------------------+
Legend: X: don't care, 0: clear, 1: set
दूसरे शब्दों में हालत कोड अहस्ताक्षरित तुलना प्रयोग करने के लिए मेल खाते हैं। वही होता है यदि आप FMOVcc
का उपयोग कर रहे हैं।
तो fcomi
के लिए या तो (या दोनों) संकार्य NaN है, यह ZF=1 PF=1 CF=1
सेट। (एफपी तुलनाओं में 4 संभावित परिणाम हैं: >
, <
, ==
, या असाधारण)। यदि आपको परवाह है कि आपका कोड NaNs के साथ क्या करता है, तो आपको अतिरिक्त jp
या jnp
की आवश्यकता हो सकती है। लेकिन हमेशा नहीं: उदाहरण के लिए, ja
केवल तभी सच है जब सीएफ = 0 और जेडएफ = 0, तो यह अनियंत्रित मामले में नहीं लिया जाएगा। यदि आप अनियंत्रित मामले को नीचे या बराबर के समान निष्पादन पथ लेना चाहते हैं, तो ja
आपको केवल इतना ही चाहिए।
यहाँ आप JA
का उपयोग करना चाहिए, यदि आप इसे प्रिंट करना चाहते हैं (यानी। if (!(f2 > f1)) { puts("hello"); }
) और JBE
यदि आप नहीं (if (!(f2 <= f1)) { puts("hello"); }
से मेल खाती है)। (ध्यान दें कि इस तथ्य के कारण यह थोड़ा उलझन में हो सकता है कि अगर हम कूद नहीं पाते हैं तो हम केवल प्रिंट करते हैं)।
अपने दूसरे प्रश्न के बारे में: डिफ़ॉल्ट fcomi
द्वारा कुछ भी पॉप नहीं करता है। आप इसके करीबी चचेरे भाई fcomip
चाहते हैं जो %st0
पॉप करता है। उपयोग के बाद आपको हमेशा एफपीयू रजिस्टर स्टैक को साफ़ करना चाहिए, इसलिए आपके सभी कार्यक्रमों में यह सब खत्म हो गया है कि आप संदेश मुद्रित करना चाहते हैं:
.section .rodata
msg: .ascii "Hallo\n\0"
f1: .float 10.0
f2: .float 9.0
.globl main
.type main, @function
main:
flds f1
flds f2
fcomip
fstp %st(0) # to clear stack
ja leb # won't jump, jbe will
pushl $msg
call printf
addl $4, %esp
leb:
pushl $0
call exit
बहुत प्रभावशाली उत्तर। बकाया। एक मामूली टिप्पणी: 'ja 'के विपरीत' jbe' है, 'jb' नहीं। –
@ रे टोल: आप बिल्कुल सही हैं। हालांकि इस मामले में इससे कोई फर्क नहीं पड़ता है, मैंने उदाहरण बदल दिया क्योंकि यह इस तरह से अधिक समझ में आता है। – user786653
अच्छा! बहुत धन्यवाद! – JustMaximumPower