-4

How do I sign contract ff12.here it is a negative number but I need to remove all the FF here but if I do that it becomes a positive number.


One definition of "sign contraction" can be found in this online copy of The Art of Assembly, as the opposite of sign-extension like x86 cbw.

Sign contraction, converting a value with some number of bits to the identical value with a fewer number of bits, is a little more troublesome. Sign extension never fails. Given an m-bit signed value you can always convert it to an n-bit number (where n > m) using sign extension. Unfortunately, given an n-bit number, you cannot always convert it to an m-bit number if m < n. For example, consider the value -448. As a 16-bit hexadecimal number, its representation is $FE40. Unfortunately, the magnitude of this number is too large to fit into an eight bit value, so you cannot sign contract it to eight bits. This is an example of an overflow condition that occurs upon conversion.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Nishant
  • 1
  • 4
  • 6
    It will not fit, since `ff12` is `-238` but the 8 bit range is `-128` to `+127`. – Jester Jan 22 '22 at 16:26
  • Can't sign contraction be performed here?? – Nishant Jan 22 '22 at 16:27
  • Here ff12 is in a 16 bit range can it be contracted to 8 bit range?? – Nishant Jan 22 '22 at 16:28
  • 2
    No it can not. It's outside of the range of 8 bit signed. – Jester Jan 22 '22 at 16:31
  • Then where can I use sign contraction can U explain – Nishant Jan 22 '22 at 16:33
  • It will fit in 9 bits, as 9 bits can hold a signed number valued from -256 to 255. The value in 9 bits would be -238 or 0x112 (hex) or 100010010 in binary. Note that the processor doesn't have 9 bit arithmetic, so to use a 9 bit number you'd want to sign extend to a size the processor naturally works with, like 16 or 32 bits. – Erik Eidt Jan 22 '22 at 17:12
  • 3
    There's no natural way to make that number (-238) to fit in 8 bits; if you force it, it will truncate, which is another way of saying overflow, and in overflow the intended value is lost and what you do get turns into some other value. That number needs at least one sign bit starting in the 2^8'th bit position. I've never heard of the term sign contraction, what is that -- do you have a reference? – Erik Eidt Jan 22 '22 at 17:20
  • Is it a 2-compliment number? – Sebastian Jan 22 '22 at 18:29
  • 1
    When we write 0xff12, that is taken as a 16-bit number: while the size is implied by the presence of 4 hex digits, the signed-ness of the data is not indicated. So, that 16-bit number could be interpreted as signed, -238, or as unsigned, 65298. If you're asking if -238 is signed, the answer is that since it is negative, it must be interpreted in a signed representation, and yes, we would use 2's complement for that. – Erik Eidt Jan 22 '22 at 18:33
  • 1
    twos complement is in the eyes of the programmer, not the bits in hardware. the bits have no meaning until used by the programmer. IF interpreted as a twos complement by the programmer then as mentioned above it is -238 if viewed by the programmer as unsigned then the value is 65298. it is both at the same time from a collection of bits stored in hardware. – old_timer Jan 22 '22 at 18:36
  • This has been made crystal clear -238 does not fit in an 8 bit number, it fits in a 9 bit but not 8. 8 bit can go from -128 to 127 if interpreted as signed. 9 bit from -256 to +255. There is no magic that can fix this in a natural way as mentioned above. – old_timer Jan 22 '22 at 18:37
  • The question about the twos compliment was to the OP. Even when it is used in most of today's hardware. As there is no solution in 8 bit, let's make sure of the format. Other typical number formats either have no solution for 0xFF12. – Sebastian Jan 22 '22 at 18:45
  • 2
    What result do you want? Saturation instead of truncation, like Brendan's answer is showing? I googled "sign contraction" since I'd never heard of that term, and it the first hit I found (which I edited into the question) describes it as value-preserving, the opposite of sign-extension. And clearly explains that it's not always possible; some numbers don't fit in 8-bit. If you want to know about alternatives to truncation, [edit] your question to say so. – Peter Cordes Jan 22 '22 at 20:42
  • 2
    As the book notes, "Unfortunately, given an n-bit number, you cannot always convert it to an m-bit number if m < n." You found one of those cases where it is not possible. – Raymond Chen Jan 24 '22 at 01:18

1 Answers1

4

How does sign contraction work from 16 bit to 8 bit?

It doesn't (the highest 8 bits, including the sign bit if the value is too large to fit in 8 bits, are simply discarded).

Instead, you have to implement it yourself.

If "contraction" is "preserve as many bits as possible" then it might become something like:

    add ax,ax   ;carry flag = sign bit, al = lowest 7 bits shifted left
    rcr al,1    ;al = original sign bit with original lowest 7 bits

For your test value 0xFF12 (or -238 in decimal), this becomes "0xFE24 with carry flag set" after the add, then 0x92 (or -110 in decimal) after the rcr.

More examples (including corner cases):

0xFF80 (or -128) -> "0xFF00 with carry flag set" = 0x80 (or -128)

0xFF00 (or -256) -> "0xFE00 with carry flag set" = 0x80 (or -128)

0x0000 -> "0x0000 with carry flag clear" = 0x00

0x007F (or +127) -> "0x00FE with carry flag clear" = 0x007F (or +127)

0x00FF (or +255) -> "0x01FE with carry flag clear" = 0x007F (or +127)

If "contraction" is "with saturation" (clamping values) then it might be something like:

    mov bx,ax    ;bx = original 16-bit value
    cbw          ;ax = 16-bit extension of original value in AL
    cmp ax,bx    ;Did the original value fit in 8 bits?
    je .done     ; yes, AL is correct (no saturation needed)

    add bx,bx    ;carry flag = original sign bit
    mov al,0x7F
    adc al,0     ;al = 0x80 (if value was negative) or 0x7F (if value was positive)
.done:

I'm not sure if there's a better way (it looks awful and I suspect my brain isn't working today).

Brendan
  • 35,656
  • 2
  • 39
  • 66
  • What is sign contraction? (I know about truncation and overflow, but never heard of sign contraction as a term, technique, mathematical operation, or something to be performed.) – Erik Eidt Jan 22 '22 at 18:37
  • 1
    @ErikEidt: D'oh- you're right. Fixing to cover saturation (the only other possibility I can think of). – Brendan Jan 22 '22 at 18:43
  • 1
    Why should saturation return -128 or 0, as your example appears to? I'd expect -128 or 127. – ecm Jan 22 '22 at 18:48
  • 2
    @ecm: Because it's a bug - fixed now :-) – Brendan Jan 22 '22 at 18:48
  • 2
    Note that x86 has signed-saturation built-in with MMX or SSE2 `packsswb xmm0, xmm0` https://www.felixcloutier.com/x86/packsswb:packssdw. Re: your add/mov/adc, that's reasonable. GCC similarly branches, then uses `test` / `setle` / `add 127` to produce 127 or -128. https://godbolt.org/z/ocbhWPKra. I think that could be `shr ax, 15` / `add al, 127` if you're on a CPU with efficient shifts (386). clang uses cmov all the way. Another version using `>=0` to test the sign bit properly does get GCC to use `shr ax, 15`. (in 64-bit mode, followed by `add eax,127` partial-reg stall on P6-family!) – Peter Cordes Jan 22 '22 at 20:52
  • In this CppCon 2017 presentation Chandler Carruth tells, why he introduced cmov for such code in llvm and that jumps can (sometimes) be better in the end: https://youtu.be/2EWejmkKlxs – Sebastian Jan 22 '22 at 21:34
  • I don't know correctly but this term is mention in The Art of Assembly Language book – Nishant Jan 23 '22 at 03:31
  • I was having problem understanding so I asked – Nishant Jan 23 '22 at 03:32
  • @Nishant: Ah - The Art of Assembly Language is using "contraction" as the opposite of "extension", and says (paraphrased) that contraction isn't possible if the "number of bits being discarded +1" highest bits aren't the same. In that case "16-bit 0xFF12 contracted to 8-bit" isn't possible because the discarded 8 bits (0xFF, all bits set) and the next bit (which is clear) aren't all the same. Note that most people call this "truncation" and would say "it's always possible to truncate but the value may change if it doesn't fit". – Brendan Jan 24 '22 at 02:39