There you go.,
|
Thanks. I understand how to work it now, but i might not get to using it for some time as I am going to focus mainly on actually learning the language.
Next help topic:extension. I don't even have much of a clue what this does or is for. Can anyone explain this to me?
Next help topic:extension. I don't even have much of a clue what this does or is for. Can anyone explain this to me?
Learn TI-83 Plus Assembly in 28 Days wrote:
What if you want to increase the number of bits, yet want to retain the value? This problem is solved with zero extension and sign extension.
To do a sign extension, consider the numbers 64 and -64. Let's derive these numbers for various bit sizes and see if anything interesting happens. Size 64 -64
8-bit $40 $C0
16-bit $0040 $FFC0
24-bit $000040 $FFFFC0
32-bit $00000040 $FFFFFFC0
From this, we can deduce that to perform a sign extension, you copy the sign bit into every additional bit, and a zero extension is just a special case of sign extensioning where you consider the sign bit to always be zero (regardless of whether it is or not).
Zero extension on the Z80 is easy:
;Zero extend DE
LD D, 0
To do a sign extension, consider the numbers 64 and -64. Let's derive these numbers for various bit sizes and see if anything interesting happens. Size 64 -64
8-bit $40 $C0
16-bit $0040 $FFC0
24-bit $000040 $FFFFC0
32-bit $00000040 $FFFFFFC0
From this, we can deduce that to perform a sign extension, you copy the sign bit into every additional bit, and a zero extension is just a special case of sign extensioning where you consider the sign bit to always be zero (regardless of whether it is or not).
Zero extension on the Z80 is easy:
;Zero extend DE
LD D, 0
Am I just missing something here? It looks like it's supposed to be simple.
It is. He's talking about representing negative numbers in z80 with varying bit-length numbers, just making it sound complicated. All you really need to know is 0-positive=negative in z80, so if you're using 1-byte numbers, -1 is 0-1 = FF. If it's 2-byte, FFFF. see?
Oh. *kicking myself* Not as hard as it seems.
SBC and SCF. What these do is beyond me. I know they do something with the carry flag an are involved in subtraction, but that's about it.
SBC and SCF. What these do is beyond me. I know they do something with the carry flag an are involved in subtraction, but that's about it.
It's basically subtracting a 16-bit number from a second 16-bit number. If the carry flag is set, an extra 1 is subtracted.
Basically if you want 16bit subtraction do:
Code:
or a makes the carry flag = 0. Other than that, that will give you 16 bit subtraction and you don't have to worry about the carry flag. You could do:
Code:
I think (Kerm correct me if I am wrong), but that's just more code (that will do the same thing as or a).
Code:
or a
sbc hl,de (just an example, any combination approved by 28 days will work)
or a makes the carry flag = 0. Other than that, that will give you 16 bit subtraction and you don't have to worry about the carry flag. You could do:
Code:
scf
ccf
I think (Kerm correct me if I am wrong), but that's just more code (that will do the same thing as or a).
- Chipmaster
- Mythical Hermit (Posts: 1858)
- 04 Oct 2005 02:29:53 pm
- Last edited by Chipmaster on 04 Oct 2005 02:33:22 pm; edited 1 time in total
add works for both adding 8 bits to the accumulator and 16 bits to hl
Code:
sub works for only subtracting 8 bits from the accumulator
Code:
SBC will only work for subtracting from hl
Code:
Note: DON'T put those parenthases around them. And remember you can't combine registers in any of these that aren't of the same size. Also note that you can only use a and hl for the first register in these. That is a pain, but basically just remember to use a mostly for calculations and use the other registers for temporary storage.
Code:
add hl,de
;or
add a,(8 bit register or (hl))
sub works for only subtracting 8 bits from the accumulator
Code:
sub (8 bit register or (hl))
SBC will only work for subtracting from hl
Code:
SBC hl,(16 bit register)
Note: DON'T put those parenthases around them. And remember you can't combine registers in any of these that aren't of the same size. Also note that you can only use a and hl for the first register in these. That is a pain, but basically just remember to use a mostly for calculations and use the other registers for temporary storage.
Yay!! No argument this time!
When you say "accumulator", do you mean just a or a and hl? 28Days refers to both of them as accumulator, so I just want to clear that up.
When you say "accumulator", do you mean just a or a and hl? 28Days refers to both of them as accumulator, so I just want to clear that up.
The accumulator is only A. This is the 8 bit accumulator. I have never heard of hl being refered to as the accumulator. It is usually used for general purpose addressing.
Also if you are looking for more advanced math functions you have a couple of options:
for multiplying and dividing of integers less than 2bytes you can use loops of adds and sbc or sub. If you need more precision than 2 bytes, need fractions parts, need imaginary parts, or are just plain to lazy to write a routine yourself there are many bcall's for floating point number mathematical functions. Generally they require the use of Op1 and Op2. And the answer is usually stored in Op1. To store to an Op:
from a:
bcall(_setxxop1)
from hl:
bcall(_setxxxxop2) ;there is no bcall to directly store hl to op1
bcall(_op2toop1)
and to store from op1 to a register
bcall(_convop1)
which will give a rounded result in de. You will get an error if it is bigger than the register pair can hold.
Also if you are looking for more advanced math functions you have a couple of options:
for multiplying and dividing of integers less than 2bytes you can use loops of adds and sbc or sub. If you need more precision than 2 bytes, need fractions parts, need imaginary parts, or are just plain to lazy to write a routine yourself there are many bcall's for floating point number mathematical functions. Generally they require the use of Op1 and Op2. And the answer is usually stored in Op1. To store to an Op:
from a:
bcall(_setxxop1)
from hl:
bcall(_setxxxxop2) ;there is no bcall to directly store hl to op1
bcall(_op2toop1)
and to store from op1 to a register
bcall(_convop1)
which will give a rounded result in de. You will get an error if it is bigger than the register pair can hold.
Oh. 28Days calls it "the 16-bit equivalent of the accumulator", and that confused me.
Arrays: They seem to me kinda like lists and matrices, but I don't understand how to reference a specific element.
Arrays: They seem to me kinda like lists and matrices, but I don't understand how to reference a specific element.
Well, they are just like lists. Except you have to think of assembly different than any other language. Unlike them, you store directly to and from memory. This means its up to you to create algorithms to use lists and to do anything with memory. There is no syntax for it, but there is a general form. Basically you must decide how many bytes each element is. You must define a starting address. You need an address to store what element you want (optional but can be useful). Here is an example of how to use an array:
Code:
Code:
element .equ AppBackUpScreen ;assuming element is the one we want to reference
Arraybase .equ AppBackUpScreen+1
#Define elementsize 1 ;varies depending on how big each element is
ld b,elementsize-1
ld a,b
or a
jr z,skip ;remember that djnz decrements before it checks for zero so you must do this to prevent against the case where b=zero initially
ld a,element
ld c,a
loop:
add a,c ;multiply by element size
djnz loop
; a now = the offset from the base ie. in L1(3) a would equal 3
skip:
ld hl,Arraybase
ld d,0
ld e,a
add hl,de ;adds the offset to the base to find the address of the element
;now (hl) is the element you wanted to address
okay. I haven't learned "jr z" and "djnz" yet, s o would I be correct in assuming that they are used for relative addressing? That looks like what they're for in your example. And "or a " sets the carry flag to zero, right?
shoot sorry, I am jumping way ahead. Let's see if I can explain this in basic terms. Jr is a jump similar to Basics goto. Jr z means that it will jump to the address next to it if the zero flag is set. DJNZ is used for loops similar to basics for loop. It decrements b and then jumps to the address next to it if b!=0. You will soon learn these are the only conditionals in ASM. Or not only resets the carry flag. That is just a by-product of its true operation. Lets take a look at or-ing to binary numbers:
Code:
now how is this used in asm:
or 8bit register or number ;does this operation on the register or number and a
so or a really or-s a and a
Why is this of any use? Won't that evaluate a to be the same thing?
YES and YES, but this is still of use.
#1 flags detect it. So if we do or a we can then detect if a is zero or not and jump.
#2 it resets the carry flag (goes along with #1). The carry flag is set if a number in a register overflowed. (became >255 in an 8 bit register or >65355 in a 16 bit register (well it's close to that. I am not sure if 65355 is it exactly). So if we or a than a couldn't have overflowed because we didn't add or subtract to it so the carry flag becomes reset.
This is the same reason why xor a is the same thing as ld a,0. Also you might want to think of or a as cp 0 because they do the same thing. Why use them you ask. They are less bytes and are much faster (well relatively speaking of course )
Code:
%10101011
or%00110000
That would evaluate out to:
%10111011
now how is this used in asm:
or 8bit register or number ;does this operation on the register or number and a
so or a really or-s a and a
Why is this of any use? Won't that evaluate a to be the same thing?
YES and YES, but this is still of use.
#1 flags detect it. So if we do or a we can then detect if a is zero or not and jump.
#2 it resets the carry flag (goes along with #1). The carry flag is set if a number in a register overflowed. (became >255 in an 8 bit register or >65355 in a 16 bit register (well it's close to that. I am not sure if 65355 is it exactly). So if we or a than a couldn't have overflowed because we didn't add or subtract to it so the carry flag becomes reset.
This is the same reason why xor a is the same thing as ld a,0. Also you might want to think of or a as cp 0 because they do the same thing. Why use them you ask. They are less bytes and are much faster (well relatively speaking of course )
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.
» Go to Registration page
» Go to Registration page
» Goto page Previous 1, 2, 3, 4, 5 Next
» View previous topic :: View next topic
» View previous topic :: View next topic
Page 4 of 5
» All times are UTC - 5 Hours
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Advertisement