In order to negate multiple-word integers it would be nice if the x86 instruction set had an equivalent to the 68K NEGX
instruction (basically a negate with carry in). This would allow negation in a single pass. The best substitute I came up with is this technique. It's basic approach is to compute the 2's complement by first computing the 1's complement and than adding 1, which requires carry propagation all the way to the most significant part. We get a slight break here in that we can use the NEG
instruction for the least significant part. Remember that NEG
sets the carry if the source is not 0.
To negate a 64 bit number in EDX:EAX
(EDX
has nost significant part):;
; negate a 64 bit number
;
; input:
; edx:eax = 64 bit number
;
; output:
; edx:eax = negated 64 bit number
;
; destroys:
; eflags
;
not edx
neg eax
sbb edx, -1
To negate a 96-bit number in EDX:EBX:EAX
(EDX
has nost significant part):;
; negate a 96 bit number
;
; input:
; edx:ebx:eax = 96 bit number
;
; output:
; edx:ebx:eax = negated 96 bit number
;
; destroys:
; eflags
;
not edx
not ebx
neg eax
sbb ebx,-1
sbb edx,-1
To negate a 128-bit number in EDX:EAX:ECX:EBX
(EDX
has nost significant part):;
; negate a 128 bit number
;
; input:
; edx:eax:ecx:ebx = 128 bit number
;
; output:
; edx:eax:ecx:ebx = negated 128 bit number
;
; destroys:
; eflags
;
not edx
not eax
not ecx
neg ebx
sbb ecx,-1
sbb eax,-1
sbb edx,-1
Note that this gem may be used and CPUs lower than 386, just use 16 bit registers instead.