WinAli

from Wikipedia, the free encyclopedia

WinAli is a model assembler (see also assembly language ) for Windows and DOS . The generated machine code is executed with a model computer that is an emulation of a real processor. WinAli is intended for learning assembly language. The developer is aimed at students who already have knowledge of ( object-oriented ) high-level languages , primarily Pascal .

Data types

Ordinal

WinAli only knows one data type . According to the WinAli documentation, it is an integer . However, the data type is two bytes in size and therefore does not correspond to the Pascal data type Integeror the C data type int(on 32- bit systems) which occupy four bytes.

The fact that the WinAli data type can store signed values ​​two bytes in size makes it a Smallint(Pascal) or a short(C).

register

WinAli provides 16 registers which, however, have no specific meaning, as is the case with x86 assemblers.

Register such as CXare not implemented in WinAli. Instead, the registers are simply addressed with the numbers 0to 15.

Stack

Just as there are 16 registers, there are also 16 independent stacks that are addressed in the same way as the registers. Consequently, it depends on the context whether the character is 0interpreted as the first register or as the first stack.

variables

Since variables can only have a single data type in WinAli , it is not necessary to explicitly Smallintidentify this as . A variable wVaris defined as follows;

 wVar ds f

However, it is not only possible to define a single variable, but also a whole (constant) array rgwVar with, for example, 16 elements;

 rgwVar ds 16f

Constants

There are two ways to define constants. The more elegant of these is wTwo = 2to declare the constant as such;

 wTwo dc      '2'

However, you don't have to declare a new symbol for every constant. If you write down wTwothe number in inverted commas instead of a symbol (such as:) at a point where a variable or constant is expected, WinAli automatically declares it when assembling.

 wFive dc      '5'
 ...
 lda 0,wFive;gleichbedeutend mit:
 lda 0,'5'
 ...

syntax

Formally

The syntax of WinAli is strongly based on a real assembler such as TASM ( Borland ) or MASM ( Microsoft ). You can divide each line of code into four columns;

 label command params comment

The indenting of the words serves for better legibility.

keyword meaning
label A label or a jump destination that can be jumped to from another line. Often this column remains empty.
command Command to be executed on this line. A detailed explanation of all commands is given in the section Command Reference .
params Each command has one or two parameters , this is at least one register and, depending on the command, another register, a stack or an address to a memory location . If the command has two parameters, they are separated by a comma " , ".
comment A comment of any length, which is introduced by a " ; " or a " * " and terminated by the end of the line.

example

The following example shows the structure and appearance of a WinAli program.

 loop sta 0,wSav;wSav = r
         lda 0,cwMult
         sub 0,'1';cwMult--
         sta 0,cwMult
         cmp 0,'1'
         add 0,'1'
         mul 0,wSav;r:=cwMult*wSav
         bne loop

As you can see from the Pascal commands noted in the comment area on the right, a WinAli program is always longer and also less intuitive than a program in a high-level language such as C, C ++ or Pascal.

Command reference

There are several versions of the WinAli command syntax circulating, so the command names are different. The command ldacan be called in another version instead l. However, the number of commands is the same.

Commands

Input and output commands
ini A The value entered by the user is Asaved in the address .
outi A The Avalue stored in the address is output on the UI .
transport
lda R,A Loads the Avalue stored in the address into the register R. R:=A;
ldr R0,R1 Loads the value in the register R1into the register R0. R0:=R1;
ldcr R0,R1 Loads the complement of the value in the register R1into the register R0. R0:=-R1;
sta R,A Stores the value in the register Rin the address A. A:=R;
arithmetic
add R,A Adds the value in the address Ato the value in the register R. R:=R+A;
addr R0,R1 Adds the value of the register R1to the value of the register R0. R0:=R0+R1;
sub R,A Subtracts the value in the address Afrom the value in the register R. R:=R-A;
subr R0,R1 Subtracts the value of the register R1from the value of the register R0. R0:=R0-R1;
mul R,A Multiplies the value in the address Aby the value in the register R. R:=R*A;
mulr R0,R1 Multiplies the value of the register R1by the value of the register R0. R0:=R0*R1;
div R,A Divides the value of the register Rby the value in the address A. R:=R div A;
divr R0,R1 Divides the value of the register R0by the value of the register R1. R0:=R0 div R1;
Comparison (is evaluated relative to the first parameter)
cmp R,A Compares the value of the register Rwith the value in the address A. if (R ## A) then
cmpr R0,R1 Compares the value of the register R0with the value of the register R1. if (R0 ## R1) then
Jump (if conditional, depending on the result of a comparison)
b A Jumps to the program line Aspecified in the address (label) (in short: jumps to A ). goto A;
be A Jumps to Awhen the operands of the comparison were the same. if (R = O) then goto A;
bne A Jumps to Aif the operands of the comparison were not equal. if (R <> O) then goto A;
bh A Jumps to Aif the first operand of the comparison was greater than the second. if (R > O) then goto A;
bnl A Jumps to Aif the first operand of the comparison was greater than / equal to the second. if (R >= O) then goto A;
bnh A Jumps to Aif the first operand of the comparison was less than or equal to the second. if (R <= O) then goto A;
bl A Jumps to Aif the first operand of the comparison was smaller than the second. if (R < O) then goto A;
Jump to a subroutine (all unconditional)
bal R,A Jumps to Aand saves the return address in the register R.
balr R0,R1 Jumps to R1and saves the return address in the register R0.
la R,A Loads the address of Ainto the register R. R:=@A;
br R Jumps to the address Rstored in the register .
Stack operations
push R,S Push't the value in the register Rinto the stack S. S.Push(R);
pop R,S Pop't the top item from the stack Sinto the register R. R:=S.Pop();
top R,S Copies the top element from the stack Sinto the register R. However, the element remains in the stack. R:=S.Top
control
eoj Marks the end of the source code. end.
nop Does not perform any operation. Can be used to make the code clearer.
nopr Same effect as nop, but only occupies two instead of four bytes.

Note on the table:

  • Explanations are written in (Object) Pascal.
  • The correct notation of the code WITH line break has been omitted for the sake of clarity.

Command size

The size of an instruction is either two or four bytes.

Each command with two parameters, the second parameter of which is an address (i.e. no register and no stack), and the command nopoccupy four bytes. All other commands occupy two bytes.

Data structures

Arrays

In contrast to many other assemblers, arrays are implemented directly in WinAli. Addressing elements by directly calculating their address using an offset and the base address is therefore not necessary. When addressing an element, WinAli even performs a range check and triggers a runtime error if the index is incorrect . Has the array rgwVar been declared;

rgwVar ds 8f

Then you can address an element by loading the offset into one of the registers, 1to 15and then noting that register in brackets after the name of the array (using the register 0for indexing does not work). The offset is the relative address of the element in the array, i.e. the product of index and data size (which is always 2). The following example copies the value at the location of '3'the array rgwVarinto the variable iwDrei, using the register 1for indexing;

: iwDrei  ds      f
: rgwVar  ds      8f
: ...
: lda     1,'6'           ;Index * Datengröße = Offset <=> '3' * '2' = '6'
: lda     0,rgwVar(1)
: sta     0,iwDrei

This corresponds to the following code in Pascal or C

//Pascal:
var
  iwDrei: SmallInt;
  rgwVar: array[0..7] of SmallInt;
...
iwDrei:= rgVar[3];


//C:
short iwDrei;
short rgwVar[8]
...
iwDrei = rgwVar[3];

Saving a value in an array works in the same way.

Absolute addressing

However, there is also a second variant of addressing an element in an array. This is a bit more cumbersome because you don't use the relative offset - as above - but the absolute one. To do this, however, the address of the array must first be read out;

la      1,rgwVar        ;die absolute Adresse des ersten Elementes des Arrays
add     1,'6'
lda     0,0(1)          ;WICHTIG: Die erste 0 bezeichnet das Register 0, die zweite 0 nicht.
sta     0,iwDrei

The really practical thing about this method is the fact that you can dereference pointers to arbitrary variables . Although this is not intended by WinAli, reading and writing of values ​​is quite possible.

Stack

As already mentioned, the WinAli assembler has 16 stacks with the designations 0up to 15. For stylistic reasons, however, only one should be used, since a "real" assembler also only has one stack. However, when implementing recursive methods, it is much easier 1to use the stack to store the return addresses.

Others

You have to implement all other data structures that you need yourself, as there are no libraries etc. The best strategy for this is to write your own method (void*) malloc (char);and its counterpart free (void *,char);(in Pascal, for example, function malloc (byte): Pointer;or procedure free (Pointer,byte);) that manage a kind of memory in an array.

Objects

It would even be possible to create and release objects (in the object-oriented sense). A class TAuto could be noted as follows.

TAuto   dc      '4'     ;Größe eines Objektes dieser Klasse
FcwSize dc      '0'
FdwVelo dc      '1'
FwColor dc      '2'
FdwLast dc      '3'

See also