DIY PROM Do It Yourself PROM chip burning help. No PROM begging. No PROMs for sale. No commercial exchange. Not a referral service.

Assembly Basics: Binary Math

Thread Tools
 
Search this Thread
 
Old Feb 24, 2005 | 11:26 AM
  #1  
AlexJH's Avatar
Thread Starter
TGO Supporter
 
Joined: Jul 2000
Posts: 812
Likes: 1
Engine: 5.7L V8
Transmission: 700R4
Assembly Basics: Binary Math

Here's a good tutorial on binary math if you're not familiar with 1's and 0's:

http://www.math.grin.edu/~rebelsky/C...nt-binary.html

There are a few tricks that programmers do to optimize their programs.

The main thing is to keep track of how many clock cycles it takes to do an operation. Doing a multiply is bad, doing a divide is terrible! Very, very slow!

So how do people get around it?

There are two tricks:

1) Shifting

It's very easy and fast to multiply or divide binary numbers by powers of 2. These use the shift left or shift right instructions.

For example:

1010 shifted right by 1 place becomes 101.

In 10-based numbers that means 10 becomes 5. Shifting right by one place is a divide by 2.

1001 shifted left by 2 places becomes 100100.

In 10 based numbers that means 9 becomes 36.

2) Look up tables

These take up lots of space on the PROM, but that's less important than speed in our case.

Basically what happens is the programmer precalculates the results by hand, and sets up a table of values in the PROM. Ie to multiply by 5, a table would look like this:

0 becomes 0
1 becomes 5
2 becomes 10

etc.

It's a little more complicated in practice, but that's the basic theory behind it.



Questions, comments? Just trying to keep people excited about assembly.



My other assembly basics posts:

https://www.thirdgen.org/techbb2/sho...hreadid=272809

https://www.thirdgen.org/techbb2/sho...hreadid=269554

http://wasabi.dynu.com:8080/wiki/ind...C11Subroutines

http://wasabi.dynu.com:8080/wiki/ind...8HC11Registers
Reply
Old Feb 24, 2005 | 11:38 AM
  #2  
JPrevost's Avatar
Senior Member
 
Joined: Oct 1999
Posts: 6,621
Likes: 2
Car: 91 Red Sled
Axle/Gears: 10bolt Richmond 3.73 Torsen
That makes a lot of sence now, thanks. I always wondered why code would shift binary but it's a simple multiply or divide, wow, right there infront of my face all along. Now Binary is starting to make sence, how many ME's can say that and be serious? lol
One question though. What is the result of a shift right in GM code on 1011. That would be 101 so it just rounds off (11/2 = 5)? Or does it shift the 1 all the way around and result in 1101?
Reply
Old Feb 24, 2005 | 12:31 PM
  #3  
AlexJH's Avatar
Thread Starter
TGO Supporter
 
Joined: Jul 2000
Posts: 812
Likes: 1
Engine: 5.7L V8
Transmission: 700R4
Oh yeah I forgot to add that part... now we're getting more serious.

If you look in the pink book for the ASR and LSR instructions, the bit that gets shifted out is put into the carry bit. You can then do fancy stuff like branch if it is set, or just ignore it.

The difference between ASR and LSR is that ASR duplicates the MSbit that was shifted down. The LSR instruction simply pads it as 0.

ASR is for dealing with *signed* numbers (ie possibly negative, from (-128 to +127).

LSR is for dealing with *unsigned* numbers (from 0 to 255).

So, an ASR on 10011101 (-99 decimal) would become 11001110 (-50 decimal) with 1 in the carry bit.

The LSR on that same number would become 01001110 with 1 in the carry bit.

Clear as mud?

Edit:

When you talk about the wrap arounds, those are the rotate instructions, ROL ROR, etc.

Last edited by AlexJH; Feb 24, 2005 at 12:35 PM.
Reply
Old Feb 24, 2005 | 01:40 PM
  #4  
RBob's Avatar
Moderator
iTrader: (1)
 
Joined: Mar 2002
Posts: 18,432
Likes: 233
From: Chasing Electrons
Car: check
Engine: check
Transmission: check
Originally posted by JPrevost
One question though. What is the result of a shift right in GM code on 1011. That would be 101 so it just rounds off (11/2 = 5)? Or does it shift the 1 all the way around and result in 1101?
The result would be 101 which is a truncation. For rounding add the carry back in:

LDAA #$0B ; 0000 1011
LSRA
ADCA #0 ; add carry and zero to A

Now because of the divide by 2 (LSRA), adding the carry back can't overflow the A registor. So no need to check for overflow.


If you are doing a multiply by 2 (LSLA) then a check of the carry flag for overlfow is a good idea:

LDAA #$80 ;
LSLA ; will overflow
BCC NXT ; bra if no carry flag (no overflow)
LDAA #$FF ; load max value, clearing overflow

NXT:

RBob.
Reply
Old Feb 24, 2005 | 02:18 PM
  #5  
JPrevost's Avatar
Senior Member
 
Joined: Oct 1999
Posts: 6,621
Likes: 2
Car: 91 Red Sled
Axle/Gears: 10bolt Richmond 3.73 Torsen
Clear as muddy water.
Reply
Old Feb 25, 2005 | 07:43 PM
  #6  
Z69's Avatar
Z69
Supreme Member
 
Joined: Sep 2003
Posts: 1,409
Likes: 1
From: Texas
So how do you get an A vs an L shift in a 68hc11?
Reply
Old Feb 25, 2005 | 07:56 PM
  #7  
RBob's Avatar
Moderator
iTrader: (1)
 
Joined: Mar 2002
Posts: 18,432
Likes: 233
From: Chasing Electrons
Car: check
Engine: check
Transmission: check
Originally posted by Z69
So how do you get an A vs an L shift in a 68hc11?
Use a different instruction:

ASRA arithmetic shift right A

LSRA logical shift right A

RBob.
Reply
Old Feb 25, 2005 | 09:46 PM
  #8  
dimented24x7's Avatar
Supreme Member
iTrader: (2)
 
Joined: Jan 2002
Posts: 9,962
Likes: 5
From: Moorestown, NJ
Car: 88 Camaro SC
Engine: SFI'd 350
Transmission: TKO 500
Axle/Gears: 9-bolt w/ 3.23's
Originally posted by JPrevost
Clear as muddy water.
Logical Shift Right and Logical Shift Left are your two most important ones out of these when your doing basic working assembly. Their operation is really quite simple. Say you have 97, which is 01100001, loaded into the A accumulator. If you use LSRA, the following happens in the A accumulator in the ECM. The highest bit is loaded with a zero, and the lowest bit pops out and is loaded into the carry bit, carry flag, or whatever its called in the condition code register.

You can imagine the following happening.

you start off with A looking like:

01100001, which is equal to 97

Then with a logical shift right, all the bits slide over one to the right and b7 is loaded with 0, the result is:

00110000, which is equal to 48.

and the last 1 in the b0 place is then written into the carry bit in the condition code register. This can either be used by you at some point, or you can just leave it there and do nothing with it.

Logical shift left is the opposite. All the bits slide over to the left with b0 being loaded with 0. The highest bit, b7, is kicked out of the A accumulator when all the bits shift left. The only thing that you need to keep in mind with a logical shift left is if the result of a number is greater then 128, or binary 10000000. This literally causes the accumulator to overflow. The extra 1 spills over into the carry bit. Once this happens, you have to max out the accumulator with 255 since your result is greater then that.

One example of this with a logical shift left is: 130 x 2 = 260. In binary, this would be:100000100, or youd go from

100000100

to

1000001000

with a Logical Shift Left.

But, that result is 9 bits. Our accumulator only holds 8 bits, so our result after the operation would be 00000100, which is decimal 4. Clearly this is not 260. The reason being is that we're missing our 9th bit that was pushed out into the carry bit in the condition code register.

Even though the LSR and LSL commands are simple, theyre also quite powerful. You can also use them to retrieve bits out of a memory address without having to directly load it. You shift the address either left or right over and over agian and one by one each bit pops out. Another application is testing b0 or b7 to see if its one or zero. The bit pops out and is loaded into the carry flag. You can then use branch commands to guide the code in the desired direction depending on the result.

Last edited by dimented24x7; Feb 25, 2005 at 09:51 PM.
Reply
Old Feb 26, 2005 | 12:04 PM
  #9  
Z69's Avatar
Z69
Supreme Member
 
Joined: Sep 2003
Posts: 1,409
Likes: 1
From: Texas
Ok,
My confusion lies in the fact that there is no difference op code wise between LSL and ASL.
I was getting around to figuring out why when this thread came up. I didn't realize until just now that there are different codes for (x)SR.
Reply
Old Feb 26, 2005 | 05:39 PM
  #10  
91blackgta's Avatar
Member
 
Joined: May 2003
Posts: 138
Likes: 0
From: Lewisville, TX
Any explaination of how to use a lookup take would be useful. I am in the process of writing the code for a injector controller on a HC12. It seems a lookup table would be easier.
Reply
Old Feb 26, 2005 | 05:50 PM
  #11  
Z69's Avatar
Z69
Supreme Member
 
Joined: Sep 2003
Posts: 1,409
Likes: 1
From: Texas
L/U table

Any explaination of how to use a lookup take would be useful.
Been done.
See the link inside
Table scaling
Reply
Related Topics
Thread
Thread Starter
Forum
Replies
Last Post
InfernalVortex
Electronics
10
Apr 20, 2021 11:31 AM
oil pan 4
Fabrication
2
Oct 6, 2015 11:56 AM
skinny z
Engine/Drivetrain/Suspension Parts for Sale
5
Oct 5, 2015 06:23 PM
gord327
Transmissions and Drivetrain
19
Oct 3, 2015 01:25 PM
Dragonsys
Engine/Drivetrain/Suspension Parts for Sale
2
Sep 25, 2015 03:51 PM




All times are GMT -5. The time now is 08:18 PM.