home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Basic / MAXONB32.DMS / in.adf / docs.lha / F-Linking < prev    next >
Encoding:
Text File  |  1994-10-31  |  17.4 KB  |  620 lines

  1.  
  2. Linking with C and Assembler
  3.  
  4.  
  5.                        
  6.  
  7.  
  8.  
  9. This Appendix is intended for assembly-language
  10. and C programmers and details linkage with
  11. these languages, together with the memory maps
  12. and register usage of compiled programs. It is
  13. also for users with some knowledge of assembly
  14. language who wish to use the debugger.
  15.  
  16.  
  17. Code Generation
  18.  
  19. A BASIC source program is converted into true
  20. machine-code, there are no P-codes or
  21. interpretative run-times. The code produced
  22. distinguishes between the program area and the
  23. data area. The program area is what is written
  24. to the disk or to memory and is position
  25. dependent code, relocated either by the
  26. AmigaDOS loader in the case of disk files or
  27. the code generator itself with programs
  28. compiled directly to memory. All program code
  29. executes in user mode and is compatible with
  30. 68010, 68020, 68030 and 68040 processors.
  31. Figure F-1 shows the overall memory map of a
  32. compiled program. Note that the heap and the
  33. machine stack are not shown here.
  34.  
  35.  
  36. Register Usage
  37.  
  38. Several registers are committed to special
  39. purposes within a compiled program. These are:
  40.  
  41.  
  42. A3 - Library Pointer
  43.  
  44. In order to minimise the space and time taken
  45. for run-time library calls, register A3 is
  46. dedicated to point to either a run-time jump
  47. block (if using the shared library( or to the
  48. run-time library code hunk itself, with a $8000
  49. offset to allow a maximum of 64k for the whole
  50. library.
  51. Library calls from within the compiled code are
  52. of the form
  53.  
  54.  
  55.  JSR -offset(A3)
  56.  
  57. Library calls from within the library itself do
  58. not use A3, they use BSR statements and are
  59. resolved by the code generator during
  60. compilation.
  61.  
  62.  
  63. A4 - Local Variable Stack Frame
  64.  
  65. At the very beginning of functions and sub
  66. programs a LINK instruction is done to allocate
  67. space on the stack for local variables (and
  68. function results) and to establish a register
  69. that can be used for accessing parameters. Only
  70. space for numeric variables are immediately
  71. allocated using LINK; arrays and string
  72. descriptors are allocated afterwards using a
  73. library call. For example a sub-program which
  74. has one local integer variable starts with the
  75. instruction
  76.  
  77.  
  78.  LINK    #-2,A4
  79.  
  80. Functions and sub programs finish with a
  81. corresponding
  82.  
  83.  
  84.  UNLK    A4
  85.  RTS
  86.  
  87.  
  88.  
  89. A5 - Data Area Pointer
  90.  
  91. The startup code of a compiled program sets up
  92. A5 to point to the data area of the program
  93. which of course is always RAM. At the start of
  94. the area are the run-time globals, followed by
  95. the descriptor table (descriptors are described
  96. later). Next is the global variable area, used
  97. for storing numeric variables. There is a 32k
  98. limit on the total size of these globals, but
  99. is would take a massive unstructured BASIC
  100. program to require such a number of globals.
  101. The static arrays follow this; there is no 32K
  102. limit on these, but those within this array are
  103. accessed more quickly.
  104.  
  105.  
  106. A6 - Maths Stack
  107.  
  108. This is a special stack used for storing
  109. intermediate results of numeric calculations.
  110.  
  111.  
  112. A7 - Machine Stack
  113.  
  114. The regular machine stack used for return
  115. addresses and local variables (using A4). It is
  116. left at the place provided by the calling
  117. program unless the stack is not as large as the
  118. MINSTACK option value when it will be allocated
  119. its own memory.
  120.  
  121.  
  122. D7- Top of Stack
  123.  
  124. This register is used to hold the current value
  125. from an intermediate expression, be it a single
  126. precision numeric value (in the ST version), a
  127. long or short integer. For strings D7 is used
  128. to hold a pointer to the descriptor for that
  129. string.
  130.  
  131.  
  132. D6 - Top of Stack Extension
  133.  
  134. This register is used in conjunction with D7 to
  135. hold long results of type double on the ST
  136. version.
  137.  
  138. Code Hunk 1
  139.  
  140.  
  141.                        
  142.                        
  143.                Compiled Program
  144.                        
  145.                        
  146.  
  147. Code Hunk 2 or hbasic2.library
  148.  
  149.  
  150.                        
  151.                        
  152.                Run-time Library
  153.                        
  154.                        
  155.  
  156. Global Area A5
  157.  
  158.  
  159.                Run-time Globals
  160.                Descriptor Table
  161.                Global Variables
  162.  
  163.                  Static Arrays
  164.  
  165.                   Maths Stack
  166.  
  167.  
  168. The Heap and Descriptors
  169.  
  170. Crucial to the operation of MaxonBASIC compiled
  171. programs is the area of memory known as the
  172. heap. BASIC is one of two common languages (the
  173. other is LISP) that requires dynamic garbage
  174. collection. Owing to the way strings in the
  175. language work it is necessary to allocate
  176. memory for them as required, then, when it runs
  177. out, to re-use all the memory no longer needed.
  178. This re-allocation is known as garbage
  179. collection. Many compilers and even some
  180. interpreters do not garbage collect and, as a
  181. result, certain operations can cause out-of-
  182. memory errors even though there is a lot of
  183. unused memory left.
  184. MaxonBASIC has a very advanced memory
  185. management system (which is hidden from the
  186. user normally) whereby any memory allocation
  187. request can cause a garbage collect to occur in
  188. order to satisfy the request. There are two
  189. schemes, the old heap (KEEP) option and the new
  190. dynamic heap option.
  191. With the Old Heap, the heap itself is a single
  192. large block of memory from which allocations
  193. for string variables and arrays take their
  194. memory. At the bottom of the heap (low memory)
  195. are all the string variables, while at the top
  196. are all the arrays. Strings work their way
  197. upwards, while arrays grow downwards. Should
  198. they ever meet, a garbage collect occurs which
  199. deletes all unused strings and moves existing
  200. ones around as required. It is important to
  201. note that arrays never move in memory as a
  202. result of a garbage collect; a dynamic array
  203. can only move when you REDIM or ERASE any other
  204. array; static arrays don´t move at all.
  205. With the new dynamic heap, arrays are stored in
  206. their own areas of memory. Large dynamic arrays
  207. have their memory individually allocated from
  208. the operating system and small dynamic array
  209. allocations are pooled together. Initially
  210. strings are allocated on a heap like the one
  211. used by the Old Heap scheme but if this fills
  212. up further mini-heaps may be allocated.
  213. As items on the heap are liable, without
  214. warning, to move about, ordinary pointers are
  215. useless.
  216. For this reason strings and arrays are accessed
  217. via descriptors, which exist normally in the
  218. global area and which themselves contain actual
  219. pointers to the data on the heap. As the memory
  220. manager knows where all the descriptors are it
  221. can update their pointers when a garbage
  222. collect occurs.
  223. Incidentally, the garbage collector itself is
  224. very fast; for example it can compact around
  225. 350k of fragmented heap in under 2 seconds on a
  226. standard 8MHz 68000, so there is never any
  227. noticeable delay in the running of a program
  228. should it have to garbage collect.
  229.  
  230.  
  231. Memory Formats
  232.  
  233.  
  234.  
  235.  
  236. Single-precision Floating Point
  237.  
  238. These use the Motorola Fast Floating Point
  239. (FFP) format. The format is unusual by most
  240. standards, but was designed solely with the
  241. 68000 architecture in mind, and is as a result
  242. very fast. It is the same format as used by ST
  243. BASIC, so random access files created with the
  244. interpreter should be directly usable within
  245. the compiler.
  246. The sign bit is 0 for positive numbers and 1
  247. for negative numbers. The mantissa has an
  248. implied binary point at bit 32 and thus ranges
  249. in value from 0.5 to <1.0. The exponent is held
  250. in excess -64. The number zero is represented
  251. with 32 bits of zero.
  252.  
  253.  
  254. Double-precision Floating Point
  255.  
  256. These use the IEEE format double-precision
  257. floats, each occupying 8 bytes, i.e. two longs.
  258. The sign bit is 0 for positive numbers and 1
  259. for negative numbers. The mantissa has an
  260. assumed bit of 1; if present it would be at bit
  261. 52. The exponent is held in excess-1023. The
  262. number zero is represented with 64 bits of
  263. zero.
  264.  
  265.  
  266. Linkable code
  267.  
  268. Although this version of BASIC has many
  269. powerful features and extensions, occasionally
  270. there is a command or function that is not part
  271. of standard BASIC. Additionally, a specific
  272. task can be very time critical and need all the
  273. speed it can get. For these reasons, MaxonBASIC
  274. has the ability to call C or assembly language
  275. subroutines.
  276. BASIC has a much more complex environment and
  277. initialisation procedure than C, so it is only
  278. possible for a BASIC program to call C
  279. functions; it is not possible for C programs to
  280. call BASIC code. In addition there are certain
  281. conventions which make this process more
  282. complex, so calling assembly-language code
  283. allows much more flexibility.
  284.  
  285.  
  286. External Definition
  287.  
  288. In order to call C or assembly-language the
  289. compiler allows a program to use a special sort
  290. of DECLARE statement to indicate that a
  291. function or sub-program is written in C or
  292. assembler. Using this will automatically cause
  293. the compiler to produce linkable (rather than
  294. executable) code. If you haven´t used the
  295. Output to (TO) compiler option, the name of the
  296. output file with have .o added to it (minus the
  297. .bas extension).
  298.  
  299.  
  300. The DECLAREÉCDECL statement
  301.  
  302. The special form of the DECLARE statement is as
  303. follows:
  304.  
  305.  
  306. DECLARE {SUB|FUNCTION} subname CDECL
  307. [ALIAS "externalname"]
  308. [(param_list)]
  309.  
  310.  The ALIAS clause is optional. The string
  311. following indicates the exact external name for
  312. the function. If an ALIAS clause is not
  313. specified the name (without any type specifier)
  314. is made lower-case and an under-score (_)
  315. character inserted at the front. This is
  316. suitable for linking with SAS/C compilers. Thus
  317. a function called cname% or a sub-program
  318. called CNAME will both use the name _cname, if
  319. there is no ALIAS clause.
  320. The parameter list is like that of a BASIC sub-
  321. program or function. That is, it specifies the
  322. types of the parameters, how many parameters
  323. there are, and whether the parameters are
  324. passed by value or reference. Normally the
  325. BYVAL keyword should be used to indicate that
  326. the parameter is passed by value (or VAL for
  327. compatibility with MaxonBASICÊ1).
  328. It is possible that the name of your external
  329. routine will clash with a symbol in the BASIC
  330. run-time system. None of the BASIC routines
  331. start with an underscore character so we
  332. recommend their use on your external names to
  333. avoid possible clashes.
  334. The use of such a DECLARE statement will
  335. automatically produce linkable code without the
  336. need for a compiler option. Compiling a
  337. linkable program to memory will give an error
  338. message
  339.  
  340.  
  341. Calling C Functions
  342.  
  343. C and assembler functions are called in a very
  344. similar way to the way standard BASIC sub-
  345. programs are called.
  346. If you are using C, call the function or sub-
  347. program in the same way as you would in C. Make
  348. sure that the types of the parameters in the
  349. BASIC DECLARE statement match the sizes of the
  350. parameters in the C code (taking particular
  351. care with integer sizes). The parameters should
  352. be in the same order in both languages.
  353. If a parameter is a pointer and you normally
  354. use the C & operator when calling the function,
  355. omit the BYVAL keyword in the parameter list.
  356. The address of the BASIC variable will then be
  357. passed to the C code.
  358.  
  359.  
  360. Calling Assembly Language Functions
  361.  
  362. For assembly language, any parameters are
  363. coerced to the appropriate type and pushed on
  364. the machine stack in reverse order (i.e. C
  365. order). Registers A3-A6 must be preserved and
  366. any return value should be in D0 (or D0 and D1
  367. if a double, D0=high longword). A string return
  368. value should be in D0 and be a pointer to a
  369. null-terminated string.
  370. You will need to ensure that your routine
  371. ´looks like´ a C function. This involves
  372. reading parameters from the stack and using an
  373. RTS to return. You must leave the parameters on
  374. the stack. The code should be assembled to
  375. linkable code and the necessary routines
  376. exported using XDEF. We recommend that you use
  377. the ALIAS facility in the DECLARE statement;
  378. otherwise you must use case sensitive code and
  379. ensure that the names you export are lower case
  380. and start with an underscore.
  381.  
  382.  
  383. Parameters
  384.  
  385. If numeric parameters are passed by value then
  386. their value (16-, 32- or 64-bits) is pushed on
  387. the stack. Double-precision parameters are
  388. passed in MaxonBASIC 3 order as required by
  389. SAS/C; not in the same order as when using the
  390. BASIC library.
  391. If variable parameters are passed then the
  392. address of the variable is pushed.
  393. Strings and arrays are passed as the address of
  394. their descriptor. The descriptor format is
  395. private and subject to change so utility
  396. routines are provided to convert them into a
  397. more useful form.
  398.  
  399.  
  400. Linking
  401.  
  402. You should end up with a linkable file from the
  403. BASIC compiler and a linkable file from the C
  404. compiler or assembler. They should be linked
  405. together using an Amiga format linker such as
  406. Slink, Blink or even Alink. You may also need
  407. to specify C compiler libraries if your C
  408. functions have referred to any.
  409. With SAS/C 6 you should use the compiler
  410. options:
  411.  
  412.  
  413. nosdata noscode nostkchk parameters=stack
  414.  
  415. which forces 32-bit variable references, 32-bit
  416. code and disables stack checking, and ensures
  417. that parameters are passed on the stack. If
  418. when you link there are undefined symbols this
  419. normally means your C is calling on a library
  420. routine. You will then have to specify the
  421. required C library when you link again, but
  422. take care that the library code does not assume
  423. any register values (e.g. for base-relative
  424. globals) or initialisation code (e.g. the Unix
  425. file system).
  426.  
  427.  
  428. C-callable Utility Routines
  429.  
  430. All utility routines may be called from
  431. assembly-language but only a few may be called
  432. from C, due to register requirements. The C-
  433. callable routines can be found in the file
  434. hbcutil.o on disk 2 which should be linked with
  435. your other code. You must generate stand-alone
  436. code to be able to use these routines.
  437.  
  438. long getbasicstr(d,&length)
  439. long d; long length;
  440.  
  441. This should be passed a string descriptor
  442. address and the address of where the length
  443. should be stored (note that strings may be
  444. >64k). The return result is the address of the
  445. string which will not be null-terminated and
  446. you are not allowed to write to the string
  447. area.
  448.  
  449. long getbasicarray(d,dims,&length)
  450. long d; short dims; long length;
  451.  
  452. This should be passed an array descriptor, the
  453. expected number of dimensions and the address
  454. of where the length should be stored. The
  455. return result is the address of the start of
  456. the array contents, guaranteed to be even. The
  457. length will be the total length in bytes taken
  458. up by the array elements. You are allowed to
  459. write to the array area.
  460.  
  461.  
  462. Assembler utility routines
  463.  
  464. The file hbasm.i in the linking directory
  465. contains various definitions for use by code
  466. called from BASIC. Your code has to decide
  467. whether it is being used by a stand-alone
  468. program or a shared-library program; if it is
  469. the latter than the symbol HBLIB should be
  470. defined before INCLUDEing hbasm.i.
  471. Most BASIC runtimes need register A5; this is
  472. why C code cannot call them. If using a shared-
  473. library program then A3 is also required. The
  474. macro CALLBAS is provided to call a BASIC
  475. runtime. Available routines are as follows:
  476.  
  477.  
  478.  
  479.  
  480. takes:    A0       the array descriptor
  481.           D0.W     the number of
  482.                    dimensions the passed
  483.                    array should have
  484. returns:  A2       the address of the
  485.                    first element in the
  486.                    array
  487.           D4.L     the total length in
  488.                    bytes taken up by the
  489.                    array elements
  490. register  D0,D4,   
  491. s used:   A1,A2
  492.  
  493.  
  494.  
  495.  
  496. takes:    A0       the string descriptor
  497. returns:  A1       the address of the
  498.                    string
  499.           D4.L     the length of the
  500.                    string
  501. register  A0,A1,D4 
  502. s used:
  503.  
  504.  
  505.  
  506.  
  507. takes:    A0       the string descriptor
  508.                    of a string-variable;
  509.                    the descriptor of a
  510.                    string value will
  511.                    have no effect if
  512.                    passed to make_string
  513.           A1       the address of your
  514.                    copy of the string
  515.           D4.L     the length of the
  516.                    string to be created
  517. register  D0-D4,   
  518. s used:   A0-A2
  519. This call allows a string parameter passed by
  520.  
  521. variable to be safely modified by the caller. A
  522.  
  523. value string parameter passed to make_string
  524.  
  525. will have no effect.
  526.  
  527.  
  528.  
  529.  
  530.  
  531. takes:    D0.L     bytes required
  532.           D1.L     type of memory (cf.
  533.                    AllocMem)
  534. returns   A0       allocated area
  535. register  D0/D1/A1 
  536. s used:
  537. This is a safe way to allocate any type of
  538.  
  539. memory and chain it to BASICs memory list, so
  540.  
  541. it will be de-allocated on program termination
  542.  
  543. (if not already de-allocated).
  544.  
  545.  
  546.  
  547.  
  548.  
  549. takes:    A0       result from
  550.                    safe_malloc
  551. register  D0-D1/A0-
  552. s used:   A1
  553.  
  554.  
  555. Re-Entrant Code
  556.  
  557. If you wish a compiled program to remain Pure
  558. (in the AmigaDOS sense) then it is your
  559. responsibility for your external routines to
  560. follow the necessary rules. We´ve done our bitÉ
  561.  
  562.  
  563. Accessing BASIC global variables from assembly
  564.  
  565. Using the Export Variables names option from
  566. the Advanced Options requester (or via the
  567. EXPORTS option) the names of your global
  568. variables will be exported as absolute symbols
  569. so that you can access them via the global
  570. register. As the BASIC variable terminators
  571. (%&!#$) are not allowed as parts of normal
  572. assembly language names, the terminators are
  573. changed to I, L, F, D and S respectively. The
  574. names are prefixed with _ for normal variable
  575. and @ for arrays. The variable names are forced
  576. to upper case. Conversely sub-program and
  577. function names are forced to lower case.
  578. Here are some BASIC names are the corresponding
  579. name to use in assembly language:
  580.  
  581.          i%         _II
  582.          fred&      _FREDL
  583.          mary!      _MARYF
  584.          john%()    @JOHNI
  585.          MARY!()    @MARYF
  586.  
  587.  
  588. Linked Examples
  589.  
  590. Here is an artificially simple example of the
  591. process, starting with the BASIC program which
  592. uses an external function to compare two short
  593. integers:
  594.  
  595.  
  596. DECLARE FUNCTION cequal% CDECL (BYVAL p1%,BYVAL
  597. p2%)
  598. PRINT cequal%(1,2),cequal%(10,10)
  599.  
  600. Now the C function:
  601.  
  602.  
  603. short cequal(a,b)
  604. short a,b
  605. {
  606. return (a==b)
  607. }
  608.  
  609. and the equivalent (Devpac) assembly-language:
  610.  
  611.  
  612.  opt l+
  613.  xdef    _cequal
  614. _cequal  move.w  4(sp),d0
  615.  cmp.w   6(sp),d0
  616.  seq d0
  617.  ext.w   d0
  618.  rts
  619.  
  620.