Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Signed 8 bit help

Status
Not open for further replies.

Mosaic

Well-Known Member
Is there an 'elegant' way to handle addition (only) in signed 8 bit asm math while keeping the max limits to 127 and -127?

It seems I have to code for 6 possibilities.

eg.

5 + 2 = +7 : double +ve
-5 + (-2) = -7 : double -ve
5 + (-2) = +3 :+ve and -ve
-5 + 2 = -3 : -ve and +ve
5 + (-6) = -1 , zero crossing to -ve
-5+ 6 = +1 , zero crossing to +ve

and then apply the max limits of +127 and -127.

So this involves evaluating the signs of each integer, clearing all the integer signs (bit7) doing the 'correct' addition or subtraction and applying the limits and then applying the correct sign. Zero crossing results will need two's complement to 'fix' the results to signed values.

This seems quite complicated, perhaps there is a better way?
 
Last edited:
Ok, I've changed to two's complement signed maths.

So the zerocrossing is handled automatically.

Still left me with a crude feeling subroutine to handle same sign overflow limiting
see here:

Code:
SumTerms	;Sum new signed factor TempL into running signed TempH. 
	btfss TempH,7
	goto Verify_Pos
	btfss TempL,7
	goto Verify_Pos
	goto Samesign_neg
Verify_Pos
	btfsc TempL,7
	goto Signdifferent
	btfsc TempH,7
	goto Signdifferent
Samesign_pos; both TempH & TempL have same + sign
	movf TempL,w
	addwf TempH,f
	btfss TempH,7; check for overflow to -ve,else
	goto Page2return
	movlw .127 ;set +ve limit
	movwf TempH
	goto Page2return ; replaces a plain return  in page2 coderam space.
Samesign_neg;
	movf TempL,w
	addwf TempH,f
	btfsc TempH,7; check for -ve overflow to +ve, else
	goto Page2return
	movlw .128 ; set -ve limit
	movwf TempH
	goto Page2return
Signdifferent; no overflow can occur, zero crossing handled automatically
	movf TempL,w
	addwf TempH,f
	goto Page2return

Is there a better way to limit +ve sums to +127 and negative sums to -128?
 
Last edited:
Mosaic This looks good

Code:
  movf    NUM2L,W     ;Add low bytes
    addwf   NUM1L,F

    movf    NUM2M,W     ;Add mid bytes
    skpnc               ;No carry_in, so just add
    incfsz  NUM2M,W     ;Add carry_in to NUM2
    addwf   NUM1M,F     ;Add and propagate carry_out
    movf    NUM2H,W     ;Add high bytes
    skpnc               ;No carry_in, so just add
    incfsz  NUM2H,W     ;Add carry_in to NUM2
    addwf   NUM1H,F     ;Add and propagate carry_out
 
Um...can u explain that a bit? How does that limit +ve #'s to 127 and -ve #'s to 128?

Edit, Also...I'm using 2 bytes, each carrying an independent #. the TempL and TempH don't mean Lo and Hi. They are just GPR I used conveniently
 
Last edited:
Here the link I'm not good at explaining math LOL It shows how 8 bit work s then gos on the 32 bit

32-bit signed integer math routines. add, subtract, multiply, divide, round, sqrt, bin2dec, dec2bin. By Peter Hemsley.

This 8bit only

If [...] your original number is in a register, you can do it with this bit of code:

COMF REG ;REG = two's-complement of REG.
INCF REG ;
or this one:

COMF REG,W ;W = two's-complement of REG
ADDLW 1 ;(REG is unchanged).
If the original number is in W, the easiest way is:

SUBLW 0 ;W = two's-complement of W.
Clyde Smith-Stubbs [clyde at htsoft.com] of HI-TECH Software says

[These snippits do not handle the problem: REG = 0x80] because there is no correct result in this case. The value 0x80 interpreted as 2's complement is legal, and equal to -128. The negative of this, 128, is NOT representable as an 8 bit 2's complement number.
From http://www.myke.com/basic.htm: Negating the Contents of "w"

If you have to Negate the contents of the "w" register, you could use the code above (after saving the value in "w" into a register) or you could use the code below for low-end devices (PIC16C5x, PIC12C5xx, PIC16C505). Any file register can be used for this code because its contents are never changed.
addwf Reg, w ; w = w + Reg
subwf Reg, w ; w = Reg - w
; w = Reg - ( w + Reg )
; w = -w
 
Last edited:
Tighter code

Well I revisited it and came up with a tighter routine, same principle:
Code:
SumTerms; Signed 8bit integer with overflow limits.  TempH / TempL are two GPRs, not hi byte / lobyte pair.
	movf TempH,w
	xorwf TempL,w ; compare sign bits
        andlw .128; mask all but bit7, sign bit
	skpz; skip if sign bits equal, else
	goto Diff_signs
;same signs, possible overflow , so sum & check polarity
	movf TempL,w
	addwf TempH,f; do sum.
	xorwf TempH,w; 0=> sign unchanged after sum, 1=> sign chg after sum
	andlw .128; mask all but bit7, sign bit
	skpnz; skip if bit 7 set ,else
	goto Page2return; no overflow occurred
;handle overflow (bit 7 set in wreg => max -ve value)
	btfsc TempH,7 ; skip next if  sign chg is to +ve from -ve, else
	movlw .127; max +ve value
	movwf TempH; apply limits
	goto Page2return
Diff_signs; no overflow possible, zero crossing auto handled.
	movf TempL,w
	addwf TempH,f
	goto Page2return
 
Last edited:
Mosaic You no simulators are no good at testing this kind of math you get the wrong output I was just playing with this
and added 140 to 140 which is 280 what do you think I get ? 140
 
Mosaic You no simulators are no good at testing this kind of math you get the wrong output I was just playing with this
and added 140 to 140 which is 280 what do you think I get ? 140

Which simulator program are you using.??
 
Mplab I was reading some of Myke Predko math code that came with My pickit2 CD and sure enough he was right
This program Shows how the Simulator can apparently
; display the wrong result to an addition operation.
;

Code:
 movlw   140                ;  Initialize Variable
  movwf   i
  
  addwf   i, w               ;  WREG = WREG + i
 
Mplab I was reading some of Myke Predko math code that came with My pickit2 CD and sure enough he was right

Code:
 movlw   140                ;  Initialize Variable
  movwf   i
  
  addwf   i, w               ;  WREG = WREG + i

Burt,
Dont know which simulators you are using, but Oshonsoft works correctly.

If you add 140 decimal to 140 decimal which should be 280 decimal, problem is the Wreg can only hold 255 decimal, so 280 - 256 = 24 which is left in the Wreg.

The binary value of the sum, assuming the Carry Bit is set 10001100 which is decimal 280.
 
Mplab simulator gives 140 in Wreg. But it should be like you show it 24 it don't

I have tried Oshonsoft It looks as if it works better then most I've tried I still like real time better
 
Status
Not open for further replies.

Latest threads

Back
Top