I am trying to refresh my memory when it comes to assembly math...please
bear with me it's been 9 years since I last looked at it.
If I have 3 numbers A, B C and I want to add them.
I would do something like...
MOV ax, A ; ax = A
ADD B, ax ; ax = A+B or ax+=B
ADD C, ax ; ax = A+ B + C or ax+=C
MOV ax, C ; c = A+B+C...
would the above be right? especially the last line.
SUB is for subtractions, (what about limits?...see below)
multiplications are
MOV ax, A
mul B; ax*=B
mul C; ax*=C
MOV C, ax ; C= ax
Again, what about overflows to DX, how do I handle them to get the 'correct'
value of C within it's own limits.
So my questions are...
Where would I define the data types of A, B and C?
Do the command, MOV ax, A, make ax the same type as A?
What are the types? do float, double even exist in assembly?
What are the limitations, (surely ax as a maximum value).
What about the overflow?
And how would you do A+B+C to ensure that the overflows are handled
properly?
Last but not least I am working on a Windows/Intel machine, does it make a
difference?
How can I test my code above?
Many thanks in advance for any help/pointers.
Simon
And here I thought that those were letters... ;-)
>
> I would do something like...
>
> MOV ax, A ; ax = A
> ADD B, ax ; ax = A+B or ax+=B
> ADD C, ax ; ax = A+ B + C or ax+=C
> MOV ax, C ; c = A+B+C...
Assuming traditional x86-style syntax, the last 3 lines need to be
reversed.
If you are using MASM, start here:
http://webster.cs.ucr.edu/Articles/X86FAQ/masm.html
There is another boat-load of links here:
http://webster.cs.ucr.edu/Articles/X86FAQ/gen3.html
Also, I highly suggest reading this book:
http://webster.cs.ucr.edu/AoA/index.html
Other nice places to get help:
http://groups.yahoo.com/group/aoaprogramming/
http://win32asm.cjb.net/
http://www.movsd.com/
http://www.programmersheaven.com/zone5/index.htm
And, just to keep out of hot water with Frank, I'd better mention NASM
-- the Netwide Assembler:
http://nasm.sourceforge.net/wakka.php?wakka=HomePage
There are some more links here too:
http://webster.cs.ucr.edu/links.htm
Hope that helps...
Nathan.
Sadly for them, today, they are not. :)
>
>>
>> I would do something like...
>>
>> MOV ax, A ; ax = A
>> ADD B, ax ; ax = A+B or ax+=B
>> ADD C, ax ; ax = A+ B + C or ax+=C
>> MOV ax, C ; c = A+B+C...
>
> Assuming traditional x86-style syntax, the last 3 lines need to be
> reversed.
What? so asuming i reverse the last 3 lines...ax knows it's going to be
A+B+C, then i do A+B+C and then A+B .. is that what you mean?
[snip links]
>
> And, just to keep out of hot water with Frank, I'd better mention NASM
> -- the Netwide Assembler:
> http://nasm.sourceforge.net/wakka.php?wakka=HomePage
who's Frank?
>
> There are some more links here too:
> http://webster.cs.ucr.edu/links.htm
>
> Hope that helps...
>
> Nathan.
Thanks
Simon
Sorry, thanks to you I now see my typo(s)
ADD ax,B ; ax = A+B or ax+=B
ADD ax,C ; ax = A+ B + C or ax+=C
MOV C, ax ; c = A+B+C...
Regards.
Simon
>
> Simon wrote:
>> Hi,
>>
>> I am trying to refresh my memory when it comes to assembly
> math...please
>> bear with me it's been 9 years since I last looked at it.
>>
>> If I have 3 numbers A, B C and I want to add them.
>
> And here I thought that those were letters... ;-)
>
>>
>> I would do something like...
>>
>> MOV ax, A ; ax = A
>> ADD B, ax ; ax = A+B or ax+=B
>> ADD C, ax ; ax = A+ B + C or ax+=C
>> MOV ax, C ; c = A+B+C...
>
> Assuming traditional x86-style syntax, the last 3 lines need to be
> reversed.
>
> http://www.programmersheaven.com/zone5/index.htm
RosAsm, Goasm, Nasm, Yasm, KetMan
Thoose all get 5 stars ! 5 Stars are the best.
RosAsm should of course have 6 stars, and be on the
dissassembler list as well.
> Hope that helps...
>
> Nathan.
>
--
"my life insists on standing still at a tremendous speed". - Freely after
Thomas Hylland Eriksen
http://TheWannabee.org
You forgot MASM, TASM, HLA, and FASM on that list.
> RosAsm should of course have 6 stars, and be on the
> dissassembler list as well.
[Yawn] I won't even waste the bandwidth. You people know my view.
--
The above was written by NoDot.
Visit the Website of NoDot:
<www.geocities.com/nodot1989/>
> -\\o//-annabee wrote:
>> RosAsm, Goasm, Nasm, Yasm, KetMan
>
> You forgot MASM, TASM, HLA, and FASM on that list.
no, Because I was only listing the one that had 5 stars
>> RosAsm should of course have 6 stars, and be on the
>> dissassembler list as well.
>
> [Yawn] I won't even waste the bandwidth. You people know my view.
:-))))) Of course. Lord Logic punish you for beeing lazy, so he refused to
enlighten you at what tool to use, and lets you hang around with the one
thats pains you.
in the nasm (an assembler) sintax it should be
segment .data
A dw 0
B dw 1
C dw 2
segment .text
mov ax, [A] ; ax = [A] = 0
add ax, [B] ; ax = ax + [B] = 1
jc .error
add ax, [C] ; ax = ax + [C] = 3
jc .error
mov [C], ax ; [C]= 3
>SUB is for subtractions, (what about limits?...see below)
>multiplications are
>
>MOV ax, A
>mul B; ax*=B
>mul C; ax*=C
>MOV C, ax ; C= ax
mov ax, [A]
mul word[B]
cmp dx, 0
jne .error
mul word[C]
cmp dx, 0
jne .error
mov [C], ax
>Again, what about overflows to DX, how do I handle them to get the 'correct'
>value of C within it's own limits.
if dx!=0 'overflow' in the word ax so the number should fit in dx:ax
and not only in ax
>So my questions are...
>
>Where would I define the data types of A, B and C?
>Do the command, MOV ax, A, make ax the same type as A?
"ax" is a cpu register "A" is a memory position, "word [A]" is what it
contain in the word size; "dword [A]" is what it contain in dword =
word[A]:word[B]
>What are the types? do float, double even exist in assembly?
in some ways yes
>What are the limitations, (surely ax as a maximum value).
>What about the overflow?
for me it (overflow) has to be detect
>And how would you do A+B+C to ensure that the overflows are handled
>properly?
see the code (if it is right)
>Last but not least I am working on a Windows/Intel machine, does it make a
>difference?
only the xx86 cpu is important for assembly
program t;
#include( "stdlib.hhf" )
static
a:word := 1;
b:word := 2;
c:word := 3;
begin t;
// Add A+B+C
mov( a, ax );
add( b, ax );
add( c, ax );
mov( ax, c ); // c:= a+b+c
// If the above are unsigned values, you can
// check for overflow as follows:
if( @c ) then // If the carry flag is set:
stdout.put( "Unsigned Overflow occurred" nl );
endif;
// If the above are signed integers, then you
// can check for overflow like this:
mov( a, ax );
add( b, ax );
add( c, ax );
mov( ax, c ); // c:= a+b+c
if( @o ) then // If the overflow flag is set:
stdout.put( "Signed Overflow occurred" nl );
endif;
// Here's another way to check for signed overflow:
try
mov( a, ax );
add( b, ax );
add( c, ax );
mov( ax, c ); // c:= a+b+c
into(); // INT(4) if overflow occurs.
anyexception
stdout.put( "Signed Overflow occurred" nl );
endtry;
// Note that you can use the exact same code for SUB,
// substituting SUB for ADD, of course.
//////////////////////////////////////////////////////////
// For multiplication, there really is no overflow.
// the destination register pair (e.g., DX:AX in your
// examples) is always big enough to hold the complete
// result. If you're trying to test for 16-bit overflow,
// then simply compare DX against zero.
//
// Another solution is to use the intmul instruction
// and check the overflow flag afterwards, e.g.,
mov( a, ax );
intmul( b, ax );
if( @o ) then
stdout.put( "Overflow occurred" nl );
endif;
// Yes, you can do float and double in assembly...
// For more details, check out "The Art of Assembly Language"
// at http://webster.cs.ucr.edu.
end t;
Cheers,
Randy Hyde
> I would do something like...
>
> MOV ax, A ; ax = A
> ADD B, ax ; ax = A+B or ax+=B
> ADD C, ax ; ax = A+ B + C or ax+=C
> MOV ax, C ; c = A+B+C...
Are you a Motorola CPU fans?
--
Free Tech (Win32Asm, Electronics..)
http://freetech.cjb.net/
Updated: April-15, 2004 / 14:35
> program t;
> #include( "stdlib.hhf" )
>
> static
> a:word := 1;
a:word := 65535
> b:word := 2;
> c:word := 3;
>
> begin t;
>
> // Add A+B+C
>
> mov( a, ax );
> add( b, ax );
> add( c, ax );
> mov( ax, c ); // c:= a+b+c
>
> // If the above are unsigned values, you can
> // check for overflow as follows:
>
> if( @c ) then // If the carry flag is set:
>
> stdout.put( "Unsigned Overflow occurred" nl );
No overflow!
Best,
Frank
> a:word := 65535
Whups!
a:word := 65535;
Best,
Frank
Oh! No Parenthesis ???!!!... Too bad!...
:)) :)) :)) :)) :))
Do you expect a VHLL Programmer to know how to
use the Carry Flag ???!!!... Too crual!...
:)) :)) :)) :)) :))
Too bad, also, that there is not a Function in
the marvelous "Standard Library" to be called
for adding 3 Values. This would have saved the
IP from having to learn anything about the Carry
Flag, at the expense of Master Pdf.
:)) :)) :)) :)) :))
Betov.
Hi Simon,
[elsewhere]
> Who's Frank
If Nasm had a fan club, I'd be president! :)
I started writing this, and got sleepy and stuck it in
"drafts" and forgot about it... Forgive the lack of
"timeliness"...
> I am trying to refresh my memory when it comes to assembly math...please
> bear with me it's been 9 years since I last looked at it.
>
> If I have 3 numbers A, B C and I want to add them.
21... hex, that is... (just joking).
If I can answer your next-to-last question first...
> Last but not least I am working on a Windows/Intel machine, does it make a
> difference?
Yes. You've got code for an "x86" processor. Made by Intel,
AMD, and a few others. Other processors - like a Mac - have
different instructions, and require entirely different
assembly language. Strictly speaking, Intel makes chips that
are not "x86", too. Don't worry about that part.
What OS you're running makes a difference - not in doing the
arithmetic, but when you want to display the result. You've
probably noticed that there's no "print" instruction for the
CPU - you have to access the OS for that (or access the
hardware directly). If you were running Linux, you'd have to
do that differently. You're running Windows, so that means
there's an old-fashioned dos "subsystem" available, too. It
makes a difference how you do a "print" depending on if
you've got a "dos program" or a "Windows program", too. What
you've posted is 16-bit code, so I assume it's for a dos
program.
{ignore the guy in clax who tells you "dos doesn't exist any
more" - it does}
What assembler you're using makes a difference, too. Looks
like you've got Masm syntax, or similar. If you were using
Nasm, you'd have to say "mov ax, [A]"...
> I would do something like...
>
> MOV ax, A ; ax = A
So far, so good...
> ADD B, ax ; ax = A+B or ax+=B
You probably want to do "add ax, B" here. What you've got
will put ax + B (or A + B) into B.
> ADD C, ax ; ax = A+ B + C or ax+=C
Likewise here, you probably want "add ax, C" - you've just
added A to C.
> MOV ax, C ; c = A+B+C...
If you want the result in C, "mov C, ax".
> would the above be right? especially the last line.
Almost... if you want the result in C. If you had another
variable called "result", you could do "mov result, ax"...
(or in Nasm syntax "mov [result], ax").
> SUB is for subtractions, (what about limits?...see below)
Well, if the result of an "add" exceeds the maximum value
that can fit in 16-bits, the carry flag is set. If a "sub"
goes below zero, the "borrow flag" is set... but it's the
same carry flag. To "catch" this condition, the "adc" (add
with carry) or "sbb" (subtract with borrow) can be used to
extend the result to another register or memory location. Or
you can just check the carry flag, scream "Overflow!", and
quit.
> multiplications are
>
> MOV ax, A
> mul B; ax*=B
> mul C; ax*=C
> MOV C, ax ; C= ax
>
> Again, what about overflows to DX, how do I handle them to get the 'correct'
> value of C within it's own limits.
Well... the result of a "mul" by a word, is dx:ax - it isn't
really an overflow, but if you want a 16-bit result it is.
Just check dx:
or dx, dx ; this doesn't change dx, just sets flags
jnz overflow
Or check the carry flag:
jc overflow
> So my questions are...
>
> Where would I define the data types of A, B and C?
Usually in the data section :) I'm not up on Masm syntax,
but I think something like:
data segment
A dw 10
B dw 14
C dw 18
data ends
code segment
commence:
mov ax, @data ; get ds poined to your data segment
mov ds, ax ; this is for an ".exe" file, don't
mov es, ax ; need it for a ".com" file
; only need to set es if using it
... ; your code
mov ah, 4Ch ; exit
int 21h
code ends
end commence ; this, paradoxically, tells where
; the "entrypoint" of the code is
I've no doubt screwed that up, someplace, but "something
like that" :)
> Do the command, MOV ax, A, make ax the same type as A?
No. ax is a 16-bit register, period. It's "A" you need to
worry about the "type" on. It, too, needs to be 16 bits.
> What are the types? do float, double even exist in assembly?
Yes, but they use a different set of instructions - those
for the "floating point unit" (FPU) - "fadd" and "fmul", for
example. Displaying the result when you're done is a lot
more complicated than displaying an integer "type". Stick to
integers, for now...
Integers come in "unsigned" and "signed" types. The CPU
doesn't know which it's dealing with - *you* need to advise
it by using different instructions. I've assumed "unsigned"
numbers - if "signed", you'd want to check the "overflow
flag" instead of the carry flag - "jo overflow". Also "imul"
instead of "mul"... "ja" - unsigned, "jg - signed, etc... A
bit much to get into here - look up "two's complement
arithmetic" for details.
> What are the limitations, (surely ax as a maximum value).
Yes, 65535 or 0FFFFh. ax can hold values from 0 to 0FFFFh -
65536 different values (unsigned). For signed numbers, -
from -32768 thru 32767.
> What about the overflow?
It just "wraps around" - 0FFFFh + 1 = 0 and a carry.
> And how would you do A+B+C to ensure that the overflows are handled
> properly?
Check the carry flag (or the overflow flag) at *each* place
an overflow could occur:
mov ax, A
add ax, B
jc overflow
add ax, C
jc overflow
mov C, ax ; if that's what you want...
...
overflow:
do something about it
Or:
mov ax, A
mul B
jc overflow
mul C
jc overflow
...
(Randy knows better than to just check at the end - he was
just knocking off a "quickie")
...
> How can I test my code above?
DEBUG is good...
Best,
Frank
> Hi,
>
> I am trying to refresh my memory when it comes to assembly
> math...please bear with me it's been 9 years since I last looked at
> it.
>
> If I have 3 numbers A, B C and I want to add them.
>
> I would do something like...
>
> MOV ax, A ; ax = A
> ADD B, ax ; ax = A+B or ax+=B
> ADD C, ax ; ax = A+ B + C or ax+=C
> MOV ax, C ; c = A+B+C...
>
> would the above be right? especially the last line.
If you are "under Windows", depending on what Assembler
you are using (here RosAsm Notation...), this should be:
mov eax D§A
add eax D§B | jc Error
add D§C eax | jc Error
> SUB is for subtractions, (what about limits?...see below)
>
> multiplications are
>
> MOV ax, A
> mul B; ax*=B
> mul C; ax*=C
> MOV C, ax ; C= ax
>
> Again, what about overflows to DX, how do I handle them to get the
> 'correct' value of C within it's own limits.
If the limit is a dWord (should be...), then, if EDX
is not 0, after MUL, you are over.
> So my questions are...
>
> Where would I define the data types of A, B and C?
> Do the command, MOV ax, A, make ax the same type as A?
>
> What are the types? do float, double even exist in assembly?
> What are the limitations, (surely ax as a maximum value).
> What about the overflow?
There is no HLL "Type" in Assembly. Only _Sizes_
(Bytes, Words, dWords,...) and one "Asm Type", that
is the differenciation between Integers and Floats,
that is "Asm Compatible", because it reflects the
real form of what is going on the Processor side.
For the various "Asm Types" available with the
Assembler you choose, ... RTFM. :)
> And how would you do A+B+C to ensure that the overflows are handled
> properly?
>
> Last but not least I am working on a Windows/Intel machine, does it
> make a difference?
> How can I test my code above?
Several Assembly Packages are available for Windows.
The most significative ones are:
RosAsm, NaGoa/NASM, FASM/Fresh.
For testing some Code experiments, RosAsm is the most
accurate Tool, as it is the only on, coming with a
fully Integrated "Source Level" Debugger. With it,
it is made quite trivial, to input some Code, to
Hit [F4] at some Intruction where you want to Step,
to hit [F6] for a Run, [F7] for stepping along your
own Source.
Plus, the Debugger Dialog itself, gives you tons of
features and Infos that make it the dream Tool for
what you mean to do.
Betov.
> You're running Windows, so that means
> there's an old-fashioned dos "subsystem" available, too. It
> makes a difference how you do a "print" depending on if
> you've got a "dos program" or a "Windows program", too. What
> you've posted is 16-bit code, so I assume it's for a dos
> program.
I would bet on a very wrong assumption, here:
All users runing Win32, would perfectly like to write
for Win32 completely. Unfortunately, due to the overload
of obsolete Web Pages about Assembly, they most often
point out, first, DOS Coding Pages, and do not hear of
the actual Assemblers.
Then, also, there is the good old propaganda, saying
that DOS Assembly is easy and that Win32 Assembly is
difficult. What tends to discourage, the guys from
even taking a look at Win32 Assembly, whereas, Win32
Assmembly, _at equivalent results_, is XXXXXXX times
easier than DOS Assembly, at _ALL_ points of view.
Well... let's hear the IP... ;)
Betov.
OK, let's see. Here the HLA game (convert any HLA to ASM)
as a DOS program. There is not a single DOS API call and
it still runs in XP. Show us an equivalent Windows program,
then we will see whether it is "XXXXXXX times easier than
DOS Assembly".
@echo off
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>hla2asm.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>hla2asm.com
echo DWKMzO???AE?B@qp?p{r?rLRwvtlL?Ro?wOG]yRGFxFGBz?Gq=?WOLBKR?>>hla2asm.com
echo wAO1yA?CxA?BzABx=EwOLbL?@oewrGrL?K?OH]cevRuvBKbBa`HGh_v?Gv>>hla2asm.com
echo BceC_uvRfbBG?oGoBGyM}AmfxBe`k?K_{am~Bf~I@_xAr?p{G}jYf~Bg@z>>hla2asm.com
echo BGK=?GKI?G?pVppirjKiV?@Ki?@o]J1irZWFBMG}@]IqBC_tLtAmBMjZv~>>hla2asm.com
echo f}Ujf~Bw?xDWGkAGAs?FiAoa}uan~B=`gCfp}?H_~BQagEfQzAc`M?FOxl>>hla2asm.com
echo ehe?WOr_P1DEBKaF?stJtV=BknH?~__@g~c?D{gPD{PFH}F@grjF@Mf}Gg>>hla2asm.com
echo bNB_BVmC}Br`yDfbx?W_r?WoF@cyI?gRLst\wLxlL?Aoj}rGEMGG~BS`r?>>hla2asm.com
echo W_ox?Jer?[F@dyB??a}?EvntJvwFM_L?@o@srGsULRcoIowULbL?BowBOk>>hla2asm.com
echo L?Bob?rwes@spOHMuvQN=Gh?v?FOFHXzpGHMuvQNGGfO=KwLs?GOivFFDz>>hla2asm.com
echo NgNBU@WDzYQpBoAjNwOUG}q?ar?mONToqbwBV`L?Bob?rwut@s~{hrA~BM>>hla2asm.com
echo eStPVEFR??B?e??OZEFR??B?j??o~BczFsDcH\jNCDE?@AB??@@???????>>hla2asm.com
echo _A???????????O?G@K??W?~???KGO?oC~?QooOsrdTsq`ThwDT?_s\@OPO>>hla2asm.com
echo @OPO@oP[@O1O@OPO=OPOxOP?DoMW@oPWxOPCDO1?DOPOxOP?xOP?0xxxxx>>hla2asm.com
hla2asm.com
The source code:
@=$100
move.w s0,r0
add.w #$1000,r0
cmp.w 2.w,r0
blo.b _10 ; genuegend Speicher vorhanden
_20: rts.w
_10: bclr.w #10,sr ; loesche direction flag
eor.w r0,r0
trap #$33 ; Reset Maus
inc.w r0 ; Maustreiber vorhanden?
bne.b _20
move.w #$0013,r0 ; 320x200 256 Farben
trap #$10
move.w #$1300,r0 ; Text ausgeben, Mode 0
move.w #$071e,r1 ; Zeile 7 Spalte 30
move.w #text1l,r2 ; Textlaenge
move.w #$0003,r3 ; Seite 0, Farbe 3
move.w #text1,r4 ; Text
trap #$10
move.w #$1300,r0 ; Text ausgeben, Mode 0
move.w #$101f,r1 ; Zeile 16 Spalte 31
move.w #text2l,r2 ; Textlaenge
move.w #$0003,r3 ; Seite 0, Farbe 3
move.w #text2,r4 ; Text
trap #$10
move.w #1,r0 ; Mauszeiger ein
trap #$33
move.w #$26,r0 ; Mausbereich abfragen
trap #$33
move.w r1,r0 ; max y
inc.w r0
mulu.w c24,r0,r1|r0
divu.w c200,r1|r0
move.w r0,cy ; Mauspixel fuer 24 Screenpixel
move.w r2,r0 ; max x
inc.w r0
mulu.w c24,r0,r1|r0
divu.w c320,r1|r0
move.w r0,cx ; Mauspixel fuer 24 Screenpixel
make_ftab:
eor.b r0,r0
move.w #$03c8,r1 ; io Adresse Farbtabelle
out.b r0,r1 ; starte mit Farbe 0
inc.w r1
move.w #ftab,r5
move.w #ftab_l,r2
_10: move.b (r5.w)+-,r0 ; naechster Tabelleneintrag dFarbe
out.b r0,r1
dbf.w r2,_10
stein: move.w #hla,r6 ; Puffer fuer hla Stein
move.w #24*24/2,r2 ; loeschen
eor.w r0,r0
rep_r2 move.w r0,(r6.w)+-{s1}
move.w #kreis,r5 ; Kreisdaten
move.w #hla,r6
move.w #1,r3 ; Farbe 1
_30: move.w #12,r4 ; 12 Zeilen fuer obere Haelfte
_10: move.b (r5.w),r2 ; Anzahl schwarze Pixel
move.w r6,-(sp)
eor.w r0,r0
rep_r2 move.b r0,(r6.w)+-{s1} ; n schwarze Pixel zeichnen
move.b #23,r2 ; 23-2n farbige Pixel
sub.b (r5.w),r2
sub.b (r5.w),r2
add.w r3,r5
move.b #1,r0 ; Farbe 1
rep_r2 move.b r0,(r6.w)+-{s1} ; 23-2n farbige Pixel ausgeben
move.w (sp)+,r6
addq.w #24,r6 ; naechste Zeile
cmp.w #kreis,r5 ; untere Haelfte ausgegeben?
blo.b _20 ; ja, dann fertig
dec.w r4 ; alle Zeilen der Haelfte ausgegeben?
bne.b _10 ; nein, dann weiter
subq.w #2,r5 ; mittlere Zeile nut einmal
neg.w r3 ; jetzt rueckwaerts zaehlen
br.b _30 ; untere Haelfte starten
_20: move.w #hla,r5 ; hla Stein zu asm Stein kopieren
move.w #asm,r6
move.w #24*24,r2
_50: move.b (r5.w)+-,r0
or.b r0,r0
beq.b _40
move.b #2,r0 ; Farbe 1 zu Farbe 2 abaendern
_40: move.b r0,(r6.w)+-{s1}
dbf.w r2,_50
text: move.w #hla_text,r5 ; "HLA" in hla Stein eintragen
move.w #hla+8*24,r6
bsr.w _100
move.w #asm_text,r5 ; "ASM" in hla Stein eintragen
move.w #asm+8*24,r6
move.w #_110,-(sp) ; anstatt: bsr.w _100, br.b _110
_100: move.w #7,r3 ; Zeichenhoehe
_30: dec.w r5 ; 24 -> 32 bit
move.l (r5.w)+-,r0
move.w #24,r2
_20: lsl.l #1,r0
bcc.b _10
move.b #0,(r6.w) ; Buchstabenpixel im Stein loeschen
_10: inc.w r6
dbf.w r2,_20
dec.w r3
bne.b _30
rts.w
_110:
loop: move.w #63,r4 ; 8x8 Steine 00yyyxxx
_20: move.w r4,r0
lsl.w #5,r0 ; 00000yyy xxx00000
lsl.b #5,m0 ; yyy00000 xxx00000
lsr.w #1,r0 ; 0yyy0000 0xxx0000
move.w r0,r6
lsr.w #1,r0 ; 00yyy000 00xxx000
add.w r0,r6 ; y*24*256 + x*24
add.w #screen,r6
move.w #hla,r5 ; 0: HLA
btst.w r4,brett
bcc.b _11
move.w #asm,r5 ; 1: ASM
_11: move.w #24,r1 ; Hoehe
_10: move.w #24,r2 ; Breite
rep_r2 move.b (r5.w)+-,(r6.w)+-{s1}
add.w #256-24,r6 ; naechste Zeile
dec.w r1
bne.b _10
dec.w r4
bpl.b _20
move.w #2,r0 ; Mauszeiger aus
trap #$33
move.w #screen,r5 ; zeiger auf screen puffer
move.w s_video,s1
move.w #24,r6 ; nicht ganz links anfangen
move.b #192,r3 ; 192 Zeilen
_30: move.w #48,r2 ; Bildbreite 48*4=192 pixel
rep_r2 move.l (r5.w)+-,(r6.w)+-{s1} ; auf Bildschirm kopieren
add.w #128,r6 ; rechter + linker Rand
addq.w #64,r5
dec.b r3 ; alle Zeilen kopiert
bne.b _30 ; nein
move.w s6,-(sp)
move.w (sp)+,s1
move.w #1,r0 ; Mauszeiger ein
trap #$33
input:
_10: move.b #$01,m0 ; Tastatur Zeichen vorhanden?
trap #$16
beq.b _30 ; nein
eor.b m0,m0 ; Zeichen lesen
trap #$16
_100: move.w #$0003,r0 ; 80x25 Zeichen
trap #$10
rts.w ; beenden
_30: move.w #03,r0 ; Mausposition abfragen
trap #$33
and.b #1,r3 ; linke Maustaste gedrueckt
beq.b _10
move.w r1,r0 ; y Position
eor.w r1,r1
divu.w cy,r1|r0 ; Skalierungsfaktor
cmp.w #7,r0 ; unterhalb Zeile 7
bhi.b _10
move.w r0,r6 ; Zeile
move.w r2,r0 ; x Position
eor.w r1,r1
divu.w cx,r1|r0 ; Skalierungsfaktor
dec.w r0 ; Bild beginnt in 2. Spalte
bmi.b _10
cmp.w #8,r0
beq.b _10 ; in Spalte 8
bhi.b _20 ; in Spalte 9+
bchg.w r0,brett-1(r6.w); n
bchg.w r0,brett+1(r6.w); s
eor.w r1,r1
bset.w r0,r1
move.b r1,m1 ; n
lsl.b #1,r1 ; wxo
add.b m1,r1 ; s
lsr.b #1,m1
add.b m1,r1
eor.b r1,brett(r6.w) ; wxo
_50: move.w #3,r0 ; Mausposition abfragen
trap #$33
and.b #1,r3 ; linke Taste losgelassen?
bne.b _50
_90: br.w loop ; auf ein neues
_20: cmpq.w #2,r6 ; Zeile 2, dann Reset
bne.b _21
move.l #0,brett
move.l #0,brett+4
br.b _90
_21: cmpq.w #5,r6 ; Zeile 5, dann Exit
beq.b _100
br.b _90
kreis: dc.b 9,6,5,4,3,2,1,1,1,0,0,0
s_video: dc.w $a000
dc.b 0
brett: dc.l $0
dc.l $0
dc.b 0
c320: dc.w 320
c200: dc.w 200
c24: dc.w 24
ftab: dc.b $00,$00,$00
dc.b $3f,$10,$08
dc.b $0c,$3f,$04
dc.b $30,$30,$30
ftab_l=@-ftab
text1: dc.b "Restart"
text1l=@-text1
text2: dc.b "Exit"
text2l=@-text2
hla_text: dc.b %11100000,%01000000,%00010001
dc.b %00010000,%01000001,%00010001
dc.b %00010000,%01000001,%00010001
dc.b %11110000,%01000001,%00011111
dc.b %00010000,%01000001,%00010001
dc.b %00010000,%01000001,%00010001
dc.b %00010000,%01111101,%00010001
asm_text: dc.b %00010000,%00111001,%00001110
dc.b %10110000,%01000101,%00010001
dc.b %10110000,%01000001,%00010001
dc.b %01010000,%00111001,%00011111
dc.b %00010000,%00000101,%00010001
dc.b %00010000,%01000101,%00010001
dc.b %00010000,%00111001,%00010001
hla: blk.b 24*24
asm: blk.b 24*24
cx: blk.w 1
cy: blk.w 1
screen: blk.b 200*256
Thanks all for the replies, i could reply to everyone but for the sake of
simplicity i think it might be better to stick to one :).
So, here goes,
First, I was quite suprised to see that there was diferent assembly code(s).
I was under the, mistaken, impression that the code was only diferent at the
processor level and that i was directly talking to the chip.
And that was exactly why Windows cannot run on Mac machines
There is obviously something between the assembler and hardware, what is it?
Assembler is nothing more than a programming language. So how do you send a
comand directly to the chip?
On anotherpoint i see that most of you said that i must throw an error as
soon as i see an overflow. So it means that you simply cannot multiply
numbers that will be greater than 16k.
So the question is how do you do a large division?
Staying in the limits of 16k, (intigers), how would you devide a 32k number
with a 16k one?
Surely it was done. I do recall my school calculator been able to handle
numbers greater than 16k.
Last but not least i saw in a "Hello world" example something like...
msg db "Hello World.$" ; where does that value get stored? It is greaker
than 16 k.
regards
Simon.
>> Then, also, there is the good old propaganda, saying
>> that DOS Assembly is easy and that Win32 Assembly is
>> difficult. What tends to discourage, the guys from
>> even taking a look at Win32 Assembly, whereas, Win32
>> Assmembly, _at equivalent results_, is XXXXXXX times
>> easier than DOS Assembly, at _ALL_ points of view.
>>
>> Well... let's hear the IP... ;)
>
> OK, let's see. Here the HLA game (convert any HLA to ASM)
> as a DOS program. There is not a single DOS API call and
> it still runs in XP. Show us an equivalent Windows program,
> then we will see whether it is "XXXXXXX times easier than
> DOS Assembly".
* Utterly out of thread, but, well...
* I begun programming in 1968. So, i also spent a
significative time at DOS writing.
* Yes, you are very impressive at doing such nice
Demos.
* I have no motivation for porting this Demo to RosAsm,
even if nice.
* If this Demo was ported to RosAsm, it would not be
much different, and way more readable, particulary,
if i would make use of HLL Constructs Macros. But,
in all cases, as you may guess, nobody is going to
make any effort for trying to read any personal
syntax. We have much enough with one. :)
Betov.
PS. Under 2000 pro, i got a hard hang after having
closed the demo... Well, i know... :)
I thought *that* might be worth rebooting to see... but I
didn't see anything. I confess I didn't look to see what the
problem might be, but instead, while I was in dos, knocked
off something that might be of more interest to the original
poster...
Here's my "dos version", someone post a "Windows version",
and Simon can tell us which he finds easier. (you'd like to
be the subject of a scientific experiment, wouldn't you
Simon? :)
Best,
Frank
; adds three values and prints result as decimal, hex, and
binary
; nasm -f bin -o add3.com add3.asm
org 100h
section .data
A dw 1
B dw 2
C dw 3
overflow_msg db "Overflow!", 10, 13, '$'
section .text
mov ax, [A]
add ax, [B]
jc overflow
add ax, [C]
jc overflow
call ax2dec
call newline
call ax2hex
call newline
call ax2bin
jmp exit
overflow:
mov ah, 9
mov dx, overflow_msg
int 21h
exit:
mov ah, 4Ch
int 21h
;--------------
;--------------
ax2dec:
push ax
push bx
push cx
push dx
mov bx, 10 ; divide by ten
xor cx, cx ; zero our counter
.push_digit:
xor dx, dx ; clear dx for the div
div bx ; dx:ax/bx -> ax quotient, dx
remainder
push dx ; save remainder
inc cx ; bump digit counter
or ax, ax ; is quotient zero?
jnz .push_digit ; no, do more
mov ah, 2 ; print character subfunction
.pop_digit:
pop dx ; get remainder back
add dl, '0' ; convert to ascii character
int 21h ; print it
loop .pop_digit ; cx times
pop dx
pop cx
pop bx
pop ax
ret
;-------------------
;-------------------
ax2hex:
push cx
push dx
mov cx, 4 ; four digits to show
.top
rol ax, 4 ; rotate one digit into position
mov dl, al ; make a copy to process
and dl, 0Fh ; mask off a single (hex) digit
cmp dl, 9 ; is it in the 'A' to 'F' range?
jbe .dec_dig ; no, skip it
add dl, 7 ; adjust
.dec_dig:
add dl, 30h ; convert to character
push ax
mov ah, 2 ; print the character
int 21h
pop ax
loop .top
pop dx
pop cx
ret
;--------------------------
;--------------------------
ax2bin:
push cx
push dx
mov cx, 16
.top
rcl ax, 1 ; rotate and set/clear carry
mov dl, '0'
adc dl, 0 ; make it '1' if carry set
push ax
mov ah, 2 ; print it
int 21h
pop ax
loop .top
pop dx
pop cx
ret
;----------------------------
;----------------------------
newline:
push ax
push dx
mov ah, 2 ; print character in dl
mov dl, 13 ; carriage return
int 21h
mov dl, 10 ; and linefeed
int 21h
pop dx
pop ax
ret
;----------------------------
> > OK, let's see. Here the HLA game (convert any HLA to ASM)
>
> I thought *that* might be worth rebooting to see... but I
> didn't see anything. I confess I didn't look to see what the
> problem might be
But a year ago it worked on your PC:
From: Frank Kotler <fbkot...@comcast.net>
Newsgroups: alt.lang.asm
Subject: Re: Video Mode 13h in windows XP ... impossible?
Date: Mon, 16 Feb 2004 16:07:57 GMT
...
> There is only one way to win the game: click and destroy any
> HLA and make it a pure ASM world.
The damn thing keeps popping back up - just like the "discussions" about
it! :)
...
> @=$100
>
> move.w s0,r0
> add.w #$1000,r0
> cmp.w 2.w,r0
> blo.b _10 ; genuegend Speicher vorhanden
C'mon Herbert - you're scaring the 12th-graders! k
Good plan. And you might want to completely ignore the
"wars" going on around here. Or jump in, if you like, but
you aren't going to convince anyone of anything. Nobody else
does. :)
> So, here goes,
> First, I was quite suprised to see that there was diferent assembly code(s).
Different *syntax* for different assemblers.
mov ax, A ; Masm
mov ax, [A] ; Nasm
movw A, %ax ! Gas
mov (A, ax); //HLA
mov.w A, r0 ; Herbert's "Daniela"
They all generate the same machine code.
> I was under the, mistaken, impression that the code was only diferent at the
> processor level and that i was directly talking to the chip.
> And that was exactly why Windows cannot run on Mac machines
Right... if we're talking about different CPUs.
> There is obviously something between the assembler and hardware, what is it?
Machine code. Just a series of numbers. Some people (like
Wolfgang) are able to write code comfortably by just writing
the numbers. Most people find it easier to use an assembler.
> Assembler is nothing more than a programming language. So how do you send a
> comand directly to the chip?
Strictly speaking, you don't "send" anything to the chip.
The chip "fetches" it. But you're talking as "directly" to
the chip as you need to.
> On anotherpoint i see that most of you said that i must throw an error as
> soon as i see an overflow.
Well... doing another "add" is going to set/clear the carry
flag again, so you need to react to it while the flags are
still set from the instruction that caused the overflow.
> So it means that you simply cannot multiply
> numbers that will be greater than 16k.
Well... 16 bits = 64k. If you want to handle numbers bigger
than 65535, you need to use more than 16 bits - another
register, or another memory location. "mul" does this
anyway. For addition, you could do something like
xor dx, dx
mov ax, [A]
add ax, [B]
adc dx, 0
jc overflow
add ax, [B]
adc dx, 0
jc overflow
add ax, [C]
adc dx, 0
jc overflow
Now the result is in dx:ax - PITA to display :) You'll never
jump to "overflow" with just 3 16-bit numbers, but I left it
in - if you were adding a long string of numbers, it might
happen. If you need to handle *really* big numbers, you'll
run out of registers, and have to use memory locations for
the result - then the amount of memory you have installed is
the only limit.
> So the question is how do you do a large division?
> Staying in the limits of 16k, (intigers), how would you devide a 32k number
> with a 16k one?
> Surely it was done. I do recall my school calculator been able to handle
> numbers greater than 16k.
Well, "div bx" divides dx:ax by bx. If the result won't fit
in 16 bits, it's an error. If you need to handle big
numbers, you'll have to do the division in pieces - high
part first, much like doing long division with pencil and
paper.
> Last but not least i saw in a "Hello world" example something like...
>
> msg db "Hello World.$" ; where does that value get stored? It is greaker
> than 16 k.
It's stored in multiple bytes, one character per byte. A
single byte will only hold values from 0 to 255, but you can
use as many bytes as you need... or as many as you've got...
Best,
Frank
Really! Didn't recognize it, but you're right. Okay...
reboot again... nope... start WinDoze... pop a dos box... it
works! In real dos, just a longish pause, and back to the
prompt. In a dos box under windows, it works. Must try to
figure out why that is... maybe when/if I get dosemu
installed...
Best,
Frank
P.S. Bet it's because I haven't got a mouse driver
installed... Reboot again? Ah, the hell with it...
> works! In real dos, just a longish pause, and back to the
> prompt.
10 processor instructions are executed if no mouse
driver is installed. If this is "a longish pause",
then maybe you need a faster PC.
> PS. Under 2000 pro, i got a hard hang after having
> closed the demo... Well, i know... :)
Maybe RosAsm was running and upset because you
executed a 16 bit assembler program, so it
decided to crash Windows?
:))
No, the only case when RosAsm decides to suicide
is when Randall Hyde tries to use it.
:))
Betov.
That's *after* unpacking from printable characters to real
code, I presume... The "longish pause" (4 or 5 seconds,
estimated) was running it from the batch file.
> If this is "a longish pause",
> then maybe you need a faster PC.
Okay.
Curiousity got the better of me, and I rebooted once again.
Runs fine with a mouse driver installed. (I use a mouse so
rarely from dos, I didn't even realize I didn't normally
install one!)
Best,
Frank
Whatever I'd write here has probably been written 100+ times before, so
I'll not waste the bandwidth or server space.
> Several Assembly Packages are available for Windows.
> The most significative ones are:
>
> RosAsm, NaGoa/NASM, FASM/Fresh.
You forgot GoAsm, MASM, TASM, and HLA.
> Betov.
Then you must be talking in Hexadecimal. ;-)
> > And, just to keep out of hot water with Frank, I'd better mention
NASM
> > -- the Netwide Assembler:
> > http://nasm.sourceforge.net/wakka.php?wakka=HomePage
>
> who's Frank?
An ornery kid who haunts these parts. There's a pic of the young cuss
here: http://szmyggenpv.com/other.htm Watch out -- he is a devout
Nasmist! ;-)
Nathan.
and if the carry flag is set from add(b, ax) and not from add(c, ax)
here you can catch it[carry flag] here?
> På 24 Feb 2005 21:47:44 GMT, skrev Betov <be...@free.fr>:
>
>> Herbert Kleebauer <kl...@unibwm.de> écrivait news:421E4399.47A49373
>> @unibwm.de:
>>
>>> Betov wrote:
>>>
>>>> PS. Under 2000 pro, i got a hard hang after having
>>>> closed the demo... Well, i know... :)
>>>
>>> Maybe RosAsm was running and upset because you
>>> executed a 16 bit assembler program, so it
>>> decided to crash Windows?
>>
>> :))
>>
>> No, the only case when RosAsm decides to suicide
>> is when Randall Hyde tries to use it.
>
> :)) Its keeps blinking at me ....
You should be allowed to remove your sun spectacles
today...
:))
Betov.
>
> You should be allowed to remove your sun spectacles
> today...
>
> :))
Oki, nothing yet. Nice demo from Marcello (Zama) btw.
Yes. The MOV instruction does not affect any flags, including
the carry flag.
BTW, in answer to Frank's original comments--
I didn't choose values to force an overflow in this example
because it demonstrates how to catch both unsigned and
signed overflow. No single value would do that job.
Of course, I could have assigned values, but I was more
interested it demonstrating the technique than anything else.
Cheers,
Randy Hyde
We *know* (except those who have read Jonathan's book :)
that mov doesn't affect any flags, but the second "add"
does!
> BTW, in answer to Frank's original comments--
> I didn't choose values to force an overflow in this example
> because it demonstrates how to catch both unsigned and
> signed overflow. No single value would do that job.
> Of course, I could have assigned values, but I was more
> interested it demonstrating the technique than anything else.
Unless HLA is doing something "behind my back", you've
demonstrated a faulty technique! Don't you need *two* of
those "if (@c)" clauses? Same for "if (@o)"...
Best,
Frank
Yep, my mistake.
Such is the problem with short code sequences intended to
demonstrate, written as a whole program. Their intent
is often misconstrued as a whole, and complete. app.
Cheers,
Randy Hyde