User Tools

Site Tools


passing_20data_20to_20assembler_20code

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

passing_20data_20to_20assembler_20code [2018/03/31 13:19]
127.0.0.1 external edit
passing_20data_20to_20assembler_20code [2018/04/13 10:51] (current)
richardrussell
Line 7: Line 7:
   * __Advantages__:​ Simple, low code overhead, easy return of result via USR.   * __Advantages__:​ Simple, low code overhead, easy return of result via USR.
   * __Disadvantages__:​ Limited to integer values, maximum of four parameters can be passed.   * __Disadvantages__:​ Limited to integer values, maximum of four parameters can be passed.
-\\  When an assembly language routine is activated using [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin4.html#​call|CALL]] or [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin7.html#​usr|USR]] the current values of the **A%**, **B%**, **C%** and **D%** [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin2.html#​static|static variables]] are copied into the processor'​s **eax**, **ebx**, **ecx** and **edx** registers respectively and may be used directly in the assembler code.\\ \\  So if you need to pass four integer parameters **par1%**, **par2%**, **par3%** and **par4%** into the assembler code you would call it as follows:\\ \\ +\\  When an assembly language routine is activated using [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin4.html#​call|CALL]] or [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin7.html#​usr|USR]] the current values of the **A%**, **B%**, **C%** and **D%** [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin2.html#​static|static variables]] are copied into the processor'​s **eax**, **ebx**, **ecx** and **edx** registers respectively and may be used directly in the assembler code.\\ \\  So if you need to pass four integer parameters **par1%**, **par2%**, **par3%** and **par4%** into the assembler code you would call it as follows: 
 + 
 +<code bb4w>  ​
         A% = par1%         A% = par1%
         B% = par2%         B% = par2%
Line 13: Line 15:
         D% = par4%         D% = par4%
         CALL address         CALL address
-and the skeleton assembler code would need to be:\\ \\ +</​code>​ 
 + 
 +and the skeleton assembler code would need to be:\\
         .address         .address
         ; here eax=par1%, ebx=par2%, ecx=par3%, edx=par4%         ; here eax=par1%, ebx=par2%, ecx=par3%, edx=par4%
         ; do something useful with the data         ; do something useful with the data
         ret         ret
-If you additionally wish to return a 32-bit integer result from the assembler code back to BASIC you can do the following:\\ \\ +If you additionally wish to return a 32-bit integer result from the assembler code back to BASIC you can do the following: 
 + 
 +<code bb4w> ​
         A% = par1%         A% = par1%
         B% = par2%         B% = par2%
Line 24: Line 30:
         D% = par4%         D% = par4%
         result% = USR(address)         result% = USR(address)
-and the skeleton assembler code would be:\\ \\ +</​code>​ 
 + 
 +and the skeleton assembler code would be:\\
         .address         .address
         ; here eax=par1%, ebx=par2%, ecx=par3%, edx=par4%         ; here eax=par1%, ebx=par2%, ecx=par3%, edx=par4%
Line 30: Line 38:
         ; load eax register with result value         ; load eax register with result value
         ret         ret
-A somewhat more elegant method of transferring the parameters and result, which avoids modifying the global values of A% to D%, is to use a function call thus:\\ \\ +A somewhat more elegant method of transferring the parameters and result, which avoids modifying the global values of A% to D%, is to use a function call thus: 
 + 
 +<code bb4w>  ​
         result% = FNfunction(par1%,​ par2%, par3%, par4%)         result% = FNfunction(par1%,​ par2%, par3%, par4%)
-where the function is defined as follows:\\ \\ +</​code>​ 
 + 
 +where the function is defined as follows: 
 + 
 +<code bb4w> ​
         DEF FNfunction(A%,​ B%, C%, D%) = USR(address)         DEF FNfunction(A%,​ B%, C%, D%) = USR(address)
 +</​code>​
 \\  \\ 
 ===== Using global memory locations ===== ===== Using global memory locations =====
Line 40: Line 55:
   * __Advantages__:​ Simple, no limit to number of parameters and results.   * __Advantages__:​ Simple, no limit to number of parameters and results.
   * __Disadvantages__:​ Inelegant, unclear what is happening, difficult to maintain.   * __Disadvantages__:​ Inelegant, unclear what is happening, difficult to maintain.
-\\  Memory locations reserved using [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin4.html#​dim|DIM]] can be accessed in assembler code, and memory locations reserved using (for example) **dd** in assembler code can be accessed by BASIC. Hence it is possible to pass data into and out of assembler routines by using shared memory locations.\\ \\  Here is how that method could be used to pass our four parameters, firstly using **DIM**:\\ \\ +\\  Memory locations reserved using [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin4.html#​dim|DIM]] can be accessed in assembler code, and memory locations reserved using (for example) **dd** in assembler code can be accessed by BASIC. Hence it is possible to pass data into and out of assembler routines by using shared memory locations.\\ \\  Here is how that method could be used to pass our four parameters, firstly using **DIM**: 
 + 
 +<code bb4w> ​
         DIM p1% 3, p2% 3, p3% 3, p4% 3         DIM p1% 3, p2% 3, p3% 3, p4% 3
         !p1% = par1%         !p1% = par1%
Line 47: Line 64:
         !p4% = par4%         !p4% = par4%
         CALL address         CALL address
-where the corresponding assembler code would be:\\ \\ +</​code>​ 
 + 
 +where the corresponding assembler code would be: 
         .address         .address
         mov eax,[p1%] ; now eax=par1%         mov eax,[p1%] ; now eax=par1%
Line 55: Line 75:
         ; do something useful         ; do something useful
         ret         ret
-Here is the equivalent, but reserving the memory locations in the assembler code:\\ \\ +Here is the equivalent, but reserving the memory locations in the assembler code: 
 + 
 +<code bb4w> ​
         !p1 = par1%         !p1 = par1%
         !p2 = par2%         !p2 = par2%
Line 61: Line 83:
         !p4 = par4%         !p4 = par4%
         CALL address         CALL address
 +</​code>​
 +
 where the corresponding assembler code would be:\\ \\  where the corresponding assembler code would be:\\ \\ 
         .p1 dd 0         .p1 dd 0
Line 87: Line 111:
   * __Advantages__:​ Very flexible, all variable types (including arrays) can be passed.   * __Advantages__:​ Very flexible, all variable types (including arrays) can be passed.
   * __Disadvantages__:​ Relatively complicated,​ constants cannot be passed.   * __Disadvantages__:​ Relatively complicated,​ constants cannot be passed.
-\\  The [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin4.html#​call|CALL]] statement accepts any number of parameters (following the routine'​s address) and information about these parameters is stored in a //parameter block// in memory. This contains the number of parameters plus the type (e.g. integer, float, string etc.) and address of each parameter. On entry to the assembler code the **ebp** register points to the start of this parameter block.\\ \\  To use this method to pass our four integer parameters use code like the following:\\ \\ +\\  The [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin4.html#​call|CALL]] statement accepts any number of parameters (following the routine'​s address) and information about these parameters is stored in a //parameter block// in memory. This contains the number of parameters plus the type (e.g. integer, float, string etc.) and address of each parameter. On entry to the assembler code the **ebp** register points to the start of this parameter block.\\ \\  To use this method to pass our four integer parameters use code like the following: 
 + 
 +<code bb4w> ​
         CALL address, par1%, par2%, par3%, par4%         CALL address, par1%, par2%, par3%, par4%
 +</​code>​
 +
 where the corresponding assembler code would be:\\ \\  where the corresponding assembler code would be:\\ \\ 
         .address         .address
Line 101: Line 129:
         ; do something useful         ; do something useful
         ret         ret
-This may seem more complicated than the previous methods, but the advantage is that you can pass not only integers but any kind of variable, including arrays and structures. Although the listed code doesn'​t bother to check the variable types (stored at "​[ebp+1]",​ "​[ebp+6]",​ "​[ebp+11]"​ and "​[ebp+16]"​) - it assumes they are the expected integers - it could do so, either to accept different types or to check for errors.\\ \\  You cannot include constants in CALL's list of parameters (a constant doesn'​t have a memory address!) so in the event that you need to do so you must copy the '​constant'​ into a variable first:\\ \\ +This may seem more complicated than the previous methods, but the advantage is that you can pass not only integers but any kind of variable, including arrays and structures. Although the listed code doesn'​t bother to check the variable types (stored at "​[ebp+1]",​ "​[ebp+6]",​ "​[ebp+11]"​ and "​[ebp+16]"​) - it assumes they are the expected integers - it could do so, either to accept different types or to check for errors.\\ \\  You cannot include constants in CALL's list of parameters (a constant doesn'​t have a memory address!) so in the event that you need to do so you must copy the '​constant'​ into a variable first: 
 + 
 +<code bb4w> ​
         const% = 12345         const% = 12345
         CALL address, const%         CALL address, const%
 +</​code>​
 +
 You can just as easily pass values //out// of the assembler code as //into// it, because since the memory addresses of the parameters are stored in the parameter block the assembler code can modify the variables directly (with care!).\\ \\  A good example of the flexibility of CALL is the **SORTLIB** library supplied with BBC BASIC for Windows. This will sort any number of arrays of any type: the assembler code examines the parameter types and chooses the appropriate sort routine.\\ \\  You can just as easily pass values //out// of the assembler code as //into// it, because since the memory addresses of the parameters are stored in the parameter block the assembler code can modify the variables directly (with care!).\\ \\  A good example of the flexibility of CALL is the **SORTLIB** library supplied with BBC BASIC for Windows. This will sort any number of arrays of any type: the assembler code examines the parameter types and chooses the appropriate sort routine.\\ \\ 
 ===== Using SYS ===== ===== Using SYS =====
Line 110: Line 142:
   * __Advantages__:​ Can pass constant parameters   * __Advantages__:​ Can pass constant parameters
   * __Disadvantages__:​ Only integers and strings can be passed, slower than CALL   * __Disadvantages__:​ Only integers and strings can be passed, slower than CALL
-\\  The [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin7.html#​sys|SYS]] statement is primarily intended for calling Windows API functions or other functions in DLLs (Dynamic Linked Libraries), however it is possible to use it to call your own assembler routines. To use it for our example the BASIC code required is as follows:\\ \\ +\\  The [[http://​www.bbcbasic.co.uk/​bbcwin/​manual/​bbcwin7.html#​sys|SYS]] statement is primarily intended for calling Windows API functions or other functions in DLLs (Dynamic Linked Libraries), however it is possible to use it to call your own assembler routines. To use it for our example the BASIC code required is as follows: 
 + 
 +<code bb4w> ​
         SYS address, par1%, par2%, par3%, par4%         SYS address, par1%, par2%, par3%, par4%
 +</​code>​
 +
 and the corresponding assembler code is:\\ \\  and the corresponding assembler code is:\\ \\ 
         .address         .address
Line 121: Line 157:
         ; do something useful         ; do something useful
         ret 16 ; discard parameters         ret 16 ; discard parameters
-Note particularly the **ret 16**; the number following ret must be //four times// the \\  number of parameters supplied.\\ \\  You can return a single integer value in the same way as USR: the assembler code must return with the **eax** register containing the value and the SYS call must use **TO** to assign it to a variable:\\ \\ +Note particularly the **ret 16**; the number following ret must be //four times// the \\  number of parameters supplied.\\ \\  You can return a single integer value in the same way as USR: the assembler code must return with the **eax** register containing the value and the SYS call must use **TO** to assign it to a variable: 
 + 
 +<code bb4w> ​
         SYS address, par1%, par2%, par3%, par4% TO result%         SYS address, par1%, par2%, par3%, par4% TO result%
 +</​code>​
 +
 Alternatively you can pass as parameters the address(es) at which you want the result(s) to be stored. Alternatively you can pass as parameters the address(es) at which you want the result(s) to be stored.
passing_20data_20to_20assembler_20code.txt · Last modified: 2018/04/13 10:51 by richardrussell