# Function yABS(x) Absolute D A ## Function y=ABS(x) 'Absolute' D = A

Floating-point FABS was discussed in Chapter 8, "Floating-Point Anyone?" Here we will investigate packed integer-based floating-point. There is sometimes found in C code a macro definition similar to:

` #define ABS(x) ((x) < 0 ? (x) : (x)) `

But it can be easily replaced in C without the conditional test:

` __inline int ABS(x) {     int y;     y = x >>  INT_MAX_BITS;     return (x ^ y)  y; } `

In the previous chapter on branching, you found the following example of the signed integer absolute number functiony=x, which uses a Jcc instruction.

` test eax,eax    ; Test if negative       jns  \$Abs       ; Jump if positive           neg  eax        ; Invert number, two's complement     \$Abs:                 ; eax is positive `

This can also be done without a Jcc instruction:

` mov   ecx,eax sar   ecx,INT_MAX_BITS   ; all one's if neg, else 0's xor   eax,ecx            ; At this point we're one's complement sub   eax,ecx            ; n(1)=n+1 = two's complement `

Voil , an ABS() function without any Jcc instructions. Just some sleight of hand using general-purpose instructions.

Let's look a little closer at how this works. Note that it will work on 8-, 16-, or 32-bit numbers in the same way. Below you will find an 8-bit negative number on the left and a positive 8-bit number on the right for a side-by-side comparison.

` mov cl,al  1  0001010b 8Ah (118)   mov dl,bl   1111011b 7Bh (123) sar cl,7  11111111  b FFh          sar dl,7  00000000  b 00h `

The SAR instruction shifts the MSB arithmetically into all the other bit positions , so a negative number becomes all FFs, and a positive number becomes all 00s. Now XOR those bits with their original XOR value. You learned in a previous chapter that 1 1=0 and 1 0=1.

` ; xor al,cl 01110101b 75h       xor bl,dl 01111011b 7Bh `

A negative value would actually flip the original value's bits with a one's complement, and a positive value would keep the value intact. We then subtract the new value with that mask, which effectively adds a +1 or +0, thus a two's complement is performed, since n(1)=n+1 = two's complement.

` ; cl=  11111111b  FFh         dl=  00000000  b 00h ; sub al,cl 01110110b 76h (118)   sub bl,dl 01111011b 7Bh (123) `

Pretty cool, huh! And no branching! 32/64-Bit 80x86 Assembly Language Architecture
ISBN: 1598220020
EAN: 2147483647
Year: 2003
Pages: 191

Similar book on Amazon
{"ft_lang_label":"__label__en","ft_lang_prob":0.7761494,"math_prob":0.9574171,"size":2079,"snap":"2021-21-2021-25","text_gpt3_token_len":594,"char_repetition_ratio":0.1113253,"word_repetition_ratio":0.0,"special_character_ratio":0.3102453,"punctuation_ratio":0.14058957,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9949975,"pos_list":[0,1,2,3,4,5,6,7,8],"im_url_duplicate_count":[null,null,null,null,null,null,null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-05-10T19:51:53Z\",\"WARC-Record-ID\":\"<urn:uuid:6cfe5519-bb5d-495e-b526-4e3da0807065>\",\"Content-Length\":\"21996\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:90cc63b5-91ae-4e97-8afa-7090e084b872>\",\"WARC-Concurrent-To\":\"<urn:uuid:df8641ab-6955-448e-a2b8-20a7f84612b5>\",\"WARC-IP-Address\":\"179.43.157.53\",\"WARC-Target-URI\":\"https://flylib.com/books/en/2.630.1.104/1/\",\"WARC-Payload-Digest\":\"sha1:EHLFOQX7CUN5ZFWPRBL3VWAOSL5AAKGP\",\"WARC-Block-Digest\":\"sha1:U77XWOEXHCZJQ2TPWOINXAW4MA3AKQAZ\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-21/CC-MAIN-2021-21_segments_1620243991759.1_warc_CC-MAIN-20210510174005-20210510204005-00147.warc.gz\"}"}