Reputation: 11
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.
Upvotes: -3
Views: 632
Reputation: 37222
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).
Upvotes: 4