On coding for nachinaschyuih.
music by COOPER
(C) CREATOR product in 1997
_______________________________
So, this article is intended
just for those who have already started learning assembler, and
wants to somehow go on, but not knows exactly how. Maybe I can
you emnogo help.
To get started shall discuss some technical terms:
bit - the smallest unit of infor mation, can be equal to 0 or
1. Byte - 8 bits put together, can take a value from 0 ... 255.
Word = 2 bytes - can take values from 0 ... 65535.
Stroke - a unit of time calculation
processor, for example, for us second only to the CPU cycles.
Each command is executed for a certain number of cycles (the
fastest of the 4-stroke) That is, so to speak, for example, some
Team:
komandakod bars
NOP # 00 4
LD HL, NN # 21 N N 10
LD A, N # 3E N 7
LD A, (NN) # 3A N N 13
SRL (IX + S) # DD # CB S # 3E 1923
Know the number of cycles during which
the command can be of some
books, such as:
"How to write a game in assembly language, or
"Programming in the native assembly language" Inforkom 1993. I
have to table is the second and I must say that
helps quite often. However, in almost
For all the tables there are small errors.
Here, like we set the initial
base and now we can continue to deepen
their knowledge.
The first thing you need to (naturally)
- Know the assembly instructions.
Second: it is necessary to know the Basic or any
another programming language, otherwise you'll have quite tight
...
CPU registers
- Used only as a reg. couple
+ You can use one
* You can only use one
AF + AF '+ IR * SP -
BC + BC '+ IX +
DE + DE '+ IY +
HL + HL '+ PC -
PC - as it and a register is not in
good sense for us, he points to
address of the processor, ie, in which
address processor executes the command. He
need the most CPU, for example in the performance of teams CALL
# nnnn processor takes PC case and throws off the stack to know
where to go. IR - This is not a register pair, and registers
Single, I-indicates the interrupt vector (in IM 2, IM 1 is not
used), and the register R is necessary for regeneration RAM, it
increases the performance of each team. A - Math register with
it can be do anything. Commands ADD, ADC
SUB, OR, XOR, AND, CPL working with him and
another data (number or register).
HL - register can be used as
arithmetic, but double-byte. Also
through it you can specify the address of data
eg LD A, (HL), in the A register will be placed this from
memory with the address contained in the HL. Or to indirect
addressing, such as JP (HL), will jump to the address contained
in register pair HL. DE, BC - almost the same, only the
register B is used as a counter operations
DJNZ # nnnn. A register pair DE is easy
varies from one command HL EX DE, HL. Y
These registers are mainly utility.
F - a flag register. Contains information on past events you
next form:
Bit name content
0 C the carry flag, he established
depending on whether the overflow register. For example if you
put 10 and 20, we get 30, it does not go for 0
or 255, and bit 0 is cleared (in 0). If we subtract 20 from 10
then obtain 246 (since the processor there are no negative
numbers) and bit 0 is set to 1. The same happens if the sum
buet more than 255.
1 N flag of addition / subtraction
2 P / V flag parity / overflow
3 not used
4 H flag poluperenosa
5 not used
6 Z flag is zero, it is set to
Depending on whether you have obtained a result equal to zero.
For example, if the 10 subtract 10, then it is set to 1 if
10 subtract 20, then will be cleared.
7 S sign flag
At first, you need only
two flags - the carry flag and zero flag.
The remaining flags are rarely used even
very experienced programmer.
IX, IY - Index registers. That is, with
use them to simply provide access to
table or array. Method of indexing
next: for example, registers A, B, C, D and
E to load the array elements (TAB)
0,1,2,3 and 4.
LD IX, TAB; set
; Register at the beginning of the table. Also
Or you can use and register IY, but
; Careful, it uses Basic for
; Their needs.
LD A, (IX +0)
LD B, (IX +1)
LD C, (IX +2)
LD D, (IX +3)
LD E, (IX +4)
SP - stack pointer. It addresses some
part of the memory allocated for a warehouse
data. It is convenient to store the address / data that must be
stored temporarily. His also use the command CALL, RET, EX
(SP), HL ... If, for example, not enough registers, and have
somewhere to keep an intermediate result, we do, for example,
PUSH HL, and HL register pair is stored on the stack, and the
SP register is reduced by 2. Do not forget that if you have
something stored on the stack, you have these data removed
prior to exit from the procedure or program, otherwise the team
will instead RET the return address of the last location in
stack value.
In the processor there are two sets of registers,
alternative set, you can use
when it is necessary to process a large number of
information and not enough of a core set.
Since both use them
can not, there is a team for their rapid metabolism.
Alternative HL'DE'BC 'are replaced by the current HL DE BC,
team EXX, registry changes on AF AF 'separate
Team EX AF, AF '. These two sets of nothing
from each other do not differ, and determine
some of them an alternative, you can not.
Editors
For writing programs in assembler need an editor (assembler)
is now a great variety of TASM, ALASM, MASM, PASM ZXASM, XAS ...
I am writing in XAS'e version 7. 446, actually
nothing better I have not seen it, but each
my, look at all possibilities and choose your own.
And to get acquainted with the editor it is desirable to read
its description. Each of the are very peculiar (purely
functional, so that you can write in any of them, but with
different amenities) so that Comments are unnecessary.
How to get started.
I personally began to write in assembly language in
The same day, as he studied it. Case
was this: I am well versed in Basic'e and wrote on it
Commanderie and base data. Speed (especially at the base
data) was just disgusting. And I
sat down to assembler, gradually learning
it translated into command line Basic'a
mash. code. In the end we got a double benefit - has made rapid
Commanderie (for the time) and learned the basics of assembly
language. Naturally, in the beginning I used the ROM
Basic'a and its routines, it is not
okay, it's even much to you
help.
You should not immediately try to do everything at
assembler, you also will be easier.
Started ...
So, now it's time to start translating
any program Basic'e in assembler, using the ROM and its
procedures. Take the book with their description (procedures
Basic'a) and start.
If you do not have anything suitable, then
You can write simultaneously on Basic'e, and
in assembler. Undesirable to use
in fractional numbers, sines and. etc.
because you work with them in assembly language is somewhat
different from Basic'a and difficult to beginners.
Let me give some explanation for
Translation Basic'a in assembler. In fact,
CPU registers are analogous to
variables in Basic'e. Cycles FOR ... NEXT
just as easily replaced by the use of
registers / memory (indirect addressing), or LD B, N. .. DJNZ
LABEL. Challenges routines GOSUB ... RETURN equivalent
CALL ... RET, GOTO N = JP # NNNN, and so on ...
Starting to write in assembly code, we get rid of
restrictions Basic'a, from its "Custody" and get the processor
to complete possession. For example, the processor no idea
is that such a screen, for it is the same piece of memory, like
everything else, so that the screen will work with you
themselves.
Moving ...
If you already know how to write, using
ROM Basic'a, then everything is fine. We must move on. We will
gradually replace its PZUshnye procedures.
Here, for example, printing a character on the screen
- One of the most desired procedures. Below
shows one of the fastest options
print character 8x8. Make print
strings, using this procedure, there is no trouble. Cause the
same procedure should be as follows:
in case A - a character code for printing
in register DE - coordinates in the screen
coordinates start from the top left
angle)
; Procedure for printing the symbol, the symbol code
And in case A, the coordinates of the register DE
PRINT LD L, A; count down the right
LD H, 0, number of bytes in
ADD HL, HL; Fonte, as
ADD HL, HL; one character is
ADD HL, HL; 8 bytes, simply multiply
; Code of the desired character by 8 and add the address to
find the font
LD BC, 15360
; Address the font in the ROM, you can create your own font and
indicate here , And his address! BUT! Be careful, this
procedure begins to transition, chat with the character code #
00, and the standard fonts (768 bytes) to ; Character code 32.
So, if you use this ; Font, put the first line in the procedure
PRINT SUB 32
ADD HL, BC
CALL POSIT
, Calculate the real address in the screen coordinates
LD B, 8
PRINT1 LD A, (HL)
LD (DE), A
INC HL
INC D
DJNZ PRINT1
RET
; The transfer of coordinates familiarity on the screen in real
S address, the coordinates are contained in register DE. D-line
E-table ; Column of your output in DE-address
POSIT LD A, D
AND 7
RRCA
RRCA
RRCA
OR E
LD E, A
LD A, D
AND # 18
OR # 40
LD D, A
RET
If necessary, you can print and color. To do this, after the
procedure call POSIT put: CALL COLOR and procedure
printing with color ready.
COLOR LD A, D
AND% 00011000
RRCA
RRCA
RRCA
OR # 58
LD B, A
LD C, E
LD A, (color); memory cell,
LD (BC), A; which stores
RET; bytes of color
Print a string. This procedure should be
specify the following items data: the register HL -
address of the text to be printed in
end of the text should always stand
byte 0, to find the end (can be replaced by any other). in
register DE - coordinates on the screen.
PR_LINE LD A, (HL)
AND A
RET Z
PUSH DE
CALL PRINT
POP DE
INC E; increment coordinate
; Print from left to right
JR PR_LINE
Seal numbers, are not rarely found the problem. Her job is to
translate the real number to a character string.
For example, take a byte for the transfer of its
in character form. To do this, select
Three variables, since it can take values from 0 to 255. We
take the registers B, C, A. B - hundreds, C - dozens, A - unit.
So, put the desired byte for transfer
register A. After exiting the procedure, we have a symbolic
representation of in registers B, C and A, as a way to display
them on screen to pick and choose.
NUM_LINE
LD B, 48
LD C, B
CP 200, and hundreds have
JR C, SM_200
LD B, "2"
SUB 200
SM_200 CP 100
JR C, SM_100
INC B
SM_100 CP 10, has dozens of
JR C, SM_10
INC C
SUB 10
JR SM_100
SM_10 ADD A, 48; unit
RET
That's all for the transfer of large numbers
did not change dramatically, just
increase the number of cycles within. Naturally, this is not
the fastest way but one of the most easily understandable.
Next, you can take a debugger and see how the procedures are
made in Rom. Try to rewrite them.
Now I think we ought to go through
the bottleneck of the program (on speed):
1. cycles - they certainly eat a lot
time, and they are not recommended
anything stored on the stack must be at least
possible to use other registers. Speaking of the registers, it
is very convenient to use as the add LX, HX, LY, HY, if
everyone else is already taken. But here is not without
difficulties, some assemblers can not survive this (the changes
registers IX, IY), and even better not to register IY change,
then come in handy if you can, then better manage IX.
Speaking on the registers, if you have
do not know, the IX register can be used as two registers
HX-byte, LX-Jr. mostly books about it
silent. Some teams with
halves of the IX and IY, formed a fairly
easy - just the team working with
H or L register to add a prefix # DD
for HX and LX, # FD for HY and LY.
Thus, for example, take a cycle in
which employs all the registers, except for IX and
have to use the stack: (preimushestva registers A, C, D, E, L,
H is not even necessary to prove)
LD B, 100, 7
LOOP PUSHBC; 11
...
POP BC; 10
DJNZLOOP; 13
Thus, the work cycle will take:
(99 * 13) +7 + (100 * (11 +10)) +7 = 3401 cycles.
Replace the case in at LX ...
LD LX, 100; 8
LOOP
...
DEC LX; 8
JP NZ, LOOP; 10
Now it turns out:
100 * (8 +10) +8 = 1808 clocks! the difference is obvious about
1. 88 times.
Also in the cycles should be avoided teams
JR x, nnnn because they take 12 cycles if the condition is
satisfied, and 7, if no. In the cycles is not feasible.
2. branching programs: let's say
you have a number and depending on it
must go to the relevant procedure
it can be implemented as follows:
LD A, (NUMBER); 13
CP 0; 7
JR Z, NUMBER0; 12 / 7
CP 1, 7
JR Z, NUMBER1; 12 / 7
CP 2, 7
JR Z, NUMBER2; 12 / 7
...
and can be as follows:
LD A, (NUMBER); 13
AND A; 4
JR Z, NUMBER0; 12 / 7
DEC A; 4
JR Z, NUMBER1; 12 / 7
DEC A; 4
JR Z, NUMBER2; 12 / 7
...
Just noticed that the second fastest. Here
I replaced the 0 at the CP AND A, because they
equally affect the flags as well AND A faster
satisfied (as for checking to 0 you can use OR A). In this
procedure, better to use the JR, as JP, so
as the probability that a particular branch of work, much less
than 50%, and this way one should choose these commands (do not
forget that JR can 'jump' only up to 128 bytes, no more and if
the procedures are at a great distance, from the JP can not
escape)
3. poll the keyboard: If you need to interview
1 ... 10 keys, you can resort to a direct reading of the ports
of the keyboard:
LD A, # 7F
IN A, (# FE)
And now lower five bits of register A will have values of the
cluster; vish: 0-bit space, symb shift, m, n, b if bit is 0,
Clavey ~ Sha pressed if 1, no. In no case do not compare ; Data
with the number! Senior 3 bits can be anything and ; The same
if you press one button does not ...? Now verify, consider, for
example, a button space, its value in a zero bit Reg. A
BIT 0, A
JP Z, PRESS_SPACE
; As possible and so, using the command rotation RRCA, it work;
em like this: the flag C> 76543210> C, that is, our result is
in ; Flag CARRY
RRCA
JP NC, PRESS_SPACE
This, incidentally, is similar to the example of razvetleniem
if you need to interview more bits, then so on and on. If the
poll all the keyboard, it is better to turn to ROM, and its
routine use, of course, if not very important time of her
performance. But if time is important, then Take all the data
ports for keyboard and write handler. By the way, the ports
Keyboard:
bits 0. 4 port
caps shift, z, x, c, v # fe 254
a, s, d, f, g # fd 253
q, w, e, r, t # fb 251
1,2,3,4,5 # f7 247
0,9,8,7,6 # ef 239
p, o, i, u, y # df 223
enter, l, k, j, h # bf 191
space, symb shift, m, n, b # 7f 127
4. If possible, replace conservation
on the stack using an alternative
register set.
We now consider the procedure for constructing a point on the
screen, it will already be complicated. It can be slow -
130-150 beats per point, or fast, but more complex, with a
table.
By the way, what is a table, and what it
eat?
Table - a bunch of bytes (or words)
which contain the information you need
quick access. It's me, of course, skazanul not specifically,
just a different me do not say. Here's a look at the 'fast
point '. She needed a small installation,
ie, before using the procedure you want to run INSTALL (once)
then you can use the procedure
construct a point indefinitely. INSTALL procedure just creates
a table. Using tables is not necessary something to consider,
which is what counts and occupies most of the time.
INSTALL; installation procedure
LD HL, PLOTT; address Spreadsheets
; To 1024 bytes for the point, the low byte of the address must
be pa; veins # 00! eg # F0 or # BC00 LD DE, # 40; address
screen LD B, E
LD C, # 80; *
LD HX, 4
LOOP3 LD LX, 8
LOOP2 LD A, 8
LOOP1 LD (HL), E
INC H
LD (HL), D
INC H
LD (HL), B
INC H
LD (HL), C
RRC C
DEC H
DEC H
DEC H
INC HL
INC D
DEC A
JR NZ, LOOP1
INC B
LD A, B
AND 31
LD B, A
LD A, D
SUB 8
LD D, A
LD A, E
ADD A, # 20
LD E, A
DEC LX
JR NZ, LOOP2
LD A, D
ADD A, 8
LD D, A
DEC HX
JR NZ, LOOP3
RET
PLOT; procedure for constructing the point
LD L, C
LD H, PLOTT/256
LD A, (HL)
INC H
LD D, (HL)
INC H
LD L, C
ADD A, (HL)
LD E, A
INC H
LD A, (DE)
OR (HL)
; OR (HL) can be replaced by XOR (HL) for applying the
principle of ; XOR, or AND (HL) for deletion of points, but
then there is a need, replace the register C at the entrance
procedure INSTALL from # 80 to # 7F LD (DE), A
RET
As can be seen from the procedure PLOT, it is almost
did not think at the entrance to her point coordinates (in B
0.191 to C 0.255) and procedure, depending on the input data
takes the appropriate bytes from the table. Try
themselves to understand what it consists of a table
it certainly will benefit.
A list of these or similar procedures, we can
keep for a long time, begin to understand themselves. What do
you want from the procedure, as make it faster, etc. And I'll
give you mathematical library of our group.
Sure, it largely will help you.
So go for it. And if you need to know
something in detail, write, and I will try to answer all your
questions.
_
(C) Copyright by Angel 2 MAIN CODE
List of procedures:
1.DIV - division
INPUT: HL <- that
DE <- what
OUTPUT: HL = HL / DE
deteriorate DE, HL, A
2.KARE - squaring
INPUT: DE <- that
OUTPUT: HL = DE * DE
deteriorate DE, HL, BC, A
3.MUL16 - umzhnozhenie
INPUT: DE <- that
BC <- what
OUTPUT: HL = DE * BC
deteriorate DE, HL, BC, A
4.RAS - square root
INPUT: HL <- from what
OUTPUT: HL = SQR (HL)
deteriorate DE, HL, BC, A
5.MHLA - multiplication
INPUT: HL <- that
A <- what
OUTPUT: HL = HL * A
deteriorate DE, HL, A
6.FACT - factorial
INPUT: A <- quotient which
OUTPUT: HL = A!
deteriorate DE, HL, A
7.MULT_N - erection
degree
INPUT: BC <- that
A <- degree
OUTPUT: HL = BC ^ A
deteriorate DE, HL, BC, A
8.PER - ra -> Degrees
INPUT: DE <- radians
OUTPUT: HL = (DE * PI) / 180
deteriorate DE, HL, BC, A
9.PER_INV - degrees -> radians
INPUT: DE <- deg
OUTPUT: HL = (DE * 180) / PI
deteriorate DE, HL, BC, A
10.SIN - f - sine function
INPUT: C <- angle, C = (0,180)
OUTPUT: A = SIN (C)
deteriorate DE, HL, BC, A
11.COS - f - cosine function
INPUT: C <- angle, C = (0,180)
OUTPUT: A = COS (C)
deteriorate DE, HL, BC, A
+ Table TABLESC - to calculate the f-functions
SIN and COS
_
; + (C) - +
; | HL = HL / DE |
; + (C) - +
DIV LD A, D
OR E
RET Z
PUSHDE, BC
LD A, 1
DIV_0 PUSHHL
SBC HL, DE
JP C, HL0
SBC HL, DE
JP C, DIV_1
DIV_01 INC A
SLA E
RL D
POP HL
JP DIV_0
DIV_1 POP HL
LD BC, 0
DIV_2 AND A
JP NZ, DIV_3
LD H, B
LD L, C
POP BC, DE
RET
DIV_3 SBC HL, DE
JP NC, DIV_4
ADD HL, DE
DIV_4 CCF
RL C
RL B
SRL D
RR E
DEC A
JP DIV_2
HL0 CP 1
JP NZ, DIV_01
POP HL
POP BC, DE
LD HL, 0
RET
; + (C) - +
; | HL = DE * DE |
; + (C) - +
KARELD B, D
LD C, E
; + (C) - +
; | HL = DE * BC |
; + (C) - +
MUL16 LD HL, 0
MUL16_2 LD A, B
OR C
RET Z
SRL B
RR C
JP NC, MUL16_0
ADD HL, DE
MUL16_0 SLA E
RL D
JP MUL16_2
RET
; + (C) - +
; | HL = SQR (HL) |
; + (C) - +
RAS LD A, H
OR L
JR Z, RAS4
RAS1
LD A, H
AND A
JP NZ, RAS11
LD A, L
CP 1
JP NZ, RAS11
LD HL, 1
RET
RAS11 LD B, H
LD C, L
SRL B
RR C
RAS_1 PUSHHL
LD D, B
LD E, C
CALLDIV
ADD HL, BC
SRL H
RR L
PUSHHL
LD D, B
LD E, C
SBC HL, DE
JP NC, RES_10
ADD HL, DE
EX DE, HL
SBC HL, DE
RES_10 LD A, H
AND A
JP NZ, RAS_0
LD A, L
CP 2
JP NC, RAS_0
POP HL, BC
RET
RAS_0 POP BC, HL
JP RAS_1
RAS_4 LD HL, 0
RET
; + (C) - +
; | HL = HL * A |
; + (C) - +
MHLAAND A
JR Z, M1H; FASTED bY CREATOR
EX DE, HL
LD HL, 0
M2H SRL A
JP NC, M3H
ADD HL, DE
M3H SLA E
RL D
AND A
JP NZ, M2H
RET
MH1 LD H, A
LD L, A
RET
; + (C) - +
; | HL = A! |
; + (C) - +
FACTLD HL, 1
EX DE, HL
FACT_ AND A
RET Z
PUSHAF
CALLMULT
EX DE, HL
POP AF
DEC A
JP FACT_
; + (C) - +
; | HL = BC ^ A |
; + (C) - +
MULT_N LD D, B
LD E, C
MULT_N0 DEC A
AND A
JP Z, MULT_N1
PUSHAF
CALLMUL16
POP AF
EX DE, HL
JP MULT_N0
MULT_N1 EX DE, HL
RET
; + (C) - +
; | HL = (DE * PI) / 180 |
; + (C) - +
PER LD BC, 314
CALLMUL16
LD DE, 180
CALLDIV
RET
; + (C) - +
; | HL = (DE * 180) / PI |
; + (C) - +
PER_INV LD BC, 180
CALLMUL16
LD DE, 314
CALLDIV
RET
; + (C) - +
; | A = SIN (C) |
; + (C) - +
SIN LD A, 90
CP C
JP NC, SIN0
RLA
SUB C
LD C, A
SIN0LD E, C
LD D, 0
LD HL, TABLESC
ADD HL, DE
LD A, (HL)
RET
; + (C) - +
; | A = COS (C) |
; + (C) - +
COS LD A, 90
CP C
JP NC, COS0
RLA
SUB C
LD C, A
COS0LD E, C
LD D, 0
LD HL, TABLESC +90
SBC HL, DE
LD A, (HL)
RET
TABLESC DEFB0, 1,3,5,7,9,10,12,14
DEFB16, 17,19,21,23,24
DEFB26, 28,29,31,33,34,36
DEFB37, 39,41,42,44,45,47
DEFB48, 50,52,53,54,56,57
DEFB59, 60,62,63,64,66,67,68
DEFB69, 71,72,73,74,75,77,78
DEFB79, 80,81,82,83,84,85
DEFB86, 87,87,88,89,90,91,91
DEFB92, 93,93,94,95,95,96
DEFB96, 97,97,97,98,98,98,99
DEFB99, 99,99,100,100,100
DEFB100, 100,100
_