{"id":240,"date":"2021-06-15T13:33:58","date_gmt":"2021-06-15T11:33:58","guid":{"rendered":"https:\/\/automatico.freevar.com\/?page_id=240"},"modified":"2021-09-29T15:43:38","modified_gmt":"2021-09-29T13:43:38","slug":"passaggio-parametri","status":"publish","type":"page","link":"https:\/\/automatico.freevar.com\/index.php\/cp-m-80-2\/hitech-c-per-z80\/passaggio-parametri\/","title":{"rendered":"Passing parameters"},"content":{"rendered":"<p><span style=\"font-size: 14pt;\"><span class=\"\">One of the phases of invoking a subroutine, in assembler language, is the passing of parameters.<\/span><\/span><br \/>\n<span style=\"font-size: 14pt;\">There are four common methods for passing parameters:<\/span><\/p>\n<ul>\n<li><span style=\"font-size: 14pt;\">through the machine registers;<\/span><\/li>\n<li><span style=\"font-size: 14pt;\">storage of the values \u200b\u200bin a predetermined memory area;<\/span><\/li>\n<li><span style=\"font-size: 14pt;\">via stack;<\/span><\/li>\n<li><span style=\"font-size: 14pt;\">writing data to the memory area immediately following the subroutine call.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-size: 14pt;\">Of these four modes, the Hi-tech C compiler uses the latter.<\/span><\/p>\n<h3>First method<\/h3>\n<p><span style=\"font-size: 14pt;\">Nel metodo di passaggio dati tramite registri, l\u2019Accumulatore \u00e8 ovviamente il registro migliore per passare un parametro a 8 bit. <\/span><br \/>\n<span style=\"font-size: 14pt;\">Il registro doppio HL invece pu\u00f2 essere utile per passare un indirizzo (16 bit). <\/span><br \/>\n<span style=\"font-size: 14pt;\">Anche il registro doppio DE potrebbe passare un indirizzo ed usare EX DE, HL per scambiare gli indirizzi. <\/span><br \/>\n<span style=\"font-size: 14pt;\">Il registro doppio BC \u00e8 adatto invece per passare valori di conteggio. <\/span><br \/>\n<span style=\"font-size: 14pt;\">I registri indice IX e IY sono ovviamente i registri pi\u00f9 adatti per memorizzare indirizzi base a strutture dati dove gli elementi<\/span><br \/>\n<span style=\"font-size: 14pt;\">sono recuperabili tramite offset. Quest\u2019ultimo metodo \u00e8 usato generalmente nelle routine di interruzione e per il salvataggio <\/span><br \/>\n<span style=\"font-size: 14pt;\">e recupero dei registri macchina.<\/span><\/p>\n<h3>Second method<\/h3>\n<p><span style=\"font-size: 14pt;\">In the method of passing data through registers, the Accumulator is obviously the best register to pass an 8-bit parameter.<\/span><br \/>\n<span style=\"font-size: 14pt;\"><span class=\"goog-text-highlight\">The double register HL, on the other hand, can be useful for passing an address (16 bits).<\/span><\/span><br \/>\n<span style=\"font-size: 14pt;\">Double register DE could also pass an address and use EX DE, HL to swap addresses.<\/span><br \/>\n<span style=\"font-size: 14pt;\">The double register BC, on the other hand, is suitable for passing count values.<\/span><br \/>\n<span style=\"font-size: 14pt;\">Index registers IX and IY are obviously the most suitable registers for storing base addresses in data structures where the elements<\/span><br \/>\n<span style=\"font-size: 14pt;\">can be recovered by offsets.\u00a0The latter method is generally used in abort routines and for saving<\/span><br \/>\n<span style=\"font-size: 14pt;\">and retrieving machine logs.<\/span><\/p>\n<h3>Third method<\/h3>\n<p><span style=\"font-size: 14pt;\">The execution of the CALL subr instruction requires the addition of the return address (address of the calling program immediately<\/span><br \/>\n<span style=\"font-size: 14pt;\">following the 3 bytes of the CALL instruction) in the base of the stack.\u00a0Recall that the stack extends from the memory address<\/span><br \/>\n<span style=\"font-size: 14pt;\">prefixed with LD SP, ind16 decreasing, that is, from high memory addresses downwards.\u00a0An address occupies 2 bytes so<\/span><br \/>\n<span style=\"font-size: 14pt;\">in the stack the parameters are in the memory cells from base + 2 upwards.<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">The invoked subroutine copies the address of the stack pointer into a memory area with LD (addr), SP or in the double register HL:<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">LD HL, 0<\/span><br \/>\n<span style=\"font-size: 14pt;\">ADD HL, SP<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">If HL is to be used in the subroutine for other needs, then register IX can be used<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">LD IX, 0<\/span><br \/>\n<span style=\"font-size: 14pt;\">ADD IX, SP<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">The calling program puts the parameters on the stack and allocates space for the results before invoking the subroutine.\u00a0Let&#8217;s see an example.\u00a0We pass an 8-bit parameter and a 16-bit parameter to a subroutine, from this we want to obtain an 8-bit result.\u00a0The first step is to prepare the place for the 8 result bits in the stack:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 21.1725%;\"><span style=\"font-size: 18.6667px;\">LD HL, -1\u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 78.8275%;\"><span style=\"font-size: 18.6667px;\">; <span class=\"goog-text-highlight\">\u00a0<\/span>one byte for the return parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.1725%;\"><span style=\"font-size: 18.6667px;\">ADD HL, SP\u00a0\u00a0<\/span><\/td>\n<td style=\"width: 78.8275%;\"><span style=\"font-size: 18.6667px;\">;<span class=\"goog-text-highlight\">\u00a0<\/span>copy stack pointer address in HL<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.1725%;\"><span style=\"font-size: 18.6667px;\">LD SP, HL\u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 78.8275%;\"><span style=\"font-size: 18.6667px;\">;\u00a0updates the stack pointer with the new value<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">Let&#8217;s see what happens in a fragment of memory:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 15.1107%;\"><span style=\"font-size: 18.6667px;\">D001\u00a0<\/span><\/td>\n<td style=\"width: 18.3221%;\">&#8230;<\/td>\n<td style=\"width: 66.5671%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 15.1107%;\"><span style=\"font-size: 18.6667px;\">D000\u00a0<\/span><\/td>\n<td style=\"width: 18.3221%;\">&#8230;<\/td>\n<td style=\"width: 66.5671%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 15.1107%;\"><span style=\"font-size: 18.6667px;\">CFFF\u00a0<\/span><\/td>\n<td style=\"width: 18.3221%;\">&#8230;<\/td>\n<td style=\"width: 66.5671%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 15.1107%;\"><span style=\"font-size: 18.6667px;\">CFFE\u00a0<\/span><\/td>\n<td style=\"width: 18.3221%;\">&#8230;<\/td>\n<td style=\"width: 66.5671%;\"><span style=\"font-size: 18.6667px;\">\u00a0\u2190 stack pointer after LD SP, HL<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 15.1107%;\"><span style=\"font-size: 18.6667px;\">CFFD<\/span><\/td>\n<td style=\"width: 18.3221%;\"><span style=\"font-size: 18.6667px;\"> return parameter<\/span><\/td>\n<td style=\"width: 66.5671%;\"><span style=\"font-size: 18.6667px;\">\u00a0\u2190 stack pointer before ADD SP, HL<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">Now let&#8217;s put in the stack the parameters to send, one of 8 bits and one of 16 bits:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 21.4712%;\"><span style=\"font-size: 18.6667px;\">LD A, (parametro8)<\/span><\/td>\n<td style=\"width: 78.5288%;\"><span style=\"font-size: 18.6667px;\">; 1 byte parameter to sent<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.4712%;\"><span style=\"font-size: 18.6667px;\">PUSH AF\u00a0<\/span><\/td>\n<td style=\"width: 78.5288%;\"><span style=\"font-size: 18.6667px;\">; but in the stack it occupies 2 bytes (AF)<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.4712%;\"><span style=\"font-size: 18.6667px;\">INC SP<\/span><\/td>\n<td style=\"width: 78.5288%;\"><span style=\"font-size: 18.6667px;\">; retrieves the place of an unnecessary byte of register F<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.4712%;\"><\/td>\n<td style=\"width: 78.5288%;\"><span style=\"font-size: 18.6667px;\">; in HL the 2-byte parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.4712%;\"><span style=\"font-size: 18.6667px;\">PUSH HL<\/span><\/td>\n<td style=\"width: 78.5288%;\"><span style=\"font-size: 18.6667px;\">; put i<span style=\"font-size: 14pt;\">nto\u00a0 stack (HL) <\/span><\/span><span style=\"font-size: 14pt;\">2-byte<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.4712%;\"><span style=\"font-size: 18.6667px;\">CALL subroutine<\/span><\/td>\n<td style=\"width: 78.5288%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">The stack pointer increment after PUSH AF is necessary because we have to pass an 8-bit parameter while PUSH AF would take up 16 bits.<\/span><br \/>\n<span style=\"font-size: 14pt;\">The second INC SP is instead used to point to the address D002 after the PUSH HL (otherwise the stack pointer would point to the address D001).<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">This is the situation of the memory area after the previous operations:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%; height: 196px;\">\n<tbody>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">D003\u00a0<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px; text-align: center;\">&#8230;<\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">D002\u00a0<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px;\"><\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><span style=\"font-size: 14pt;\">Return address from LSB subroutine<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">D001<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px;\"><\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><span style=\"font-size: 14pt;\">Return address from MSB subroutine<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">D000\u00a0<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px;\"><\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><span style=\"font-size: 14pt;\">Input parameter L<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">CFFF\u00a0<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px;\"><\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><span style=\"font-size: 14pt;\"><span class=\"\">Input parameter H<\/span><\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">CFFE\u00a0<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px;\"><\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><span style=\"font-size: 14pt;\">Input parameter A<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">CFFD<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px;\"><\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><span style=\"font-size: 14pt;\">Return parameter<\/span><\/td>\n<\/tr>\n<tr style=\"height: 28px;\">\n<td style=\"width: 15.5588%; height: 28px;\"><span style=\"font-size: 18.6667px;\">CFFC\u00a0<\/span><\/td>\n<td style=\"width: 18.1728%; height: 28px; text-align: center;\">&#8230;<\/td>\n<td style=\"width: 66.2683%; height: 28px;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">At this point the stack points to address D002 where the return address following the subroutine call resides.<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">To point to the data area you need to add 1 + 1 byte (return address) to the stack pointer:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">LD HL, 2\u00a0<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 18.6667px;\">; data area offset<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">ADD HL, SP\u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 18.6667px;\">; calculate the new address<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">LD SP, HL\u00a0<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 18.6667px;\">; updates the stack pointer with the new value<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\"><span class=\"\">The stack now points to the address D000.\u00a0<\/span><span class=\"goog-text-highlight\">The subroutine can now fetch the parameters it needs:\u00a0<\/span><\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">LD E, (HL)<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; first parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">DEC HL<\/span><\/td>\n<td style=\"width: 78.4541%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">LD D, (HL)<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; second parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">DEC HL<\/span><\/td>\n<td style=\"width: 78.4541%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">LD A, (HL)<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; third parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">EX DE, HL<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; swaps the pointer in DE and in HL the first two parameters<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\"><span class=\"\">In registers HL and A we have the passed parameters.\u00a0<\/span>After the calculations we put\u00a0the 8-bit result on the stack:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100.299%; height: 57px;\">\n<tbody>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">EX DE,HL<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; address retrieval from DE<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">DEC HL<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; HL points to CFFD, the address of the return parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.5459%;\"><span style=\"font-size: 18.6667px;\">LD (HL), A<\/span><\/td>\n<td style=\"width: 78.4541%;\"><span style=\"font-size: 14pt;\">; copy the result to the stack<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\"><span class=\"goog-text-highlight\">We adjust the stack pointer to the right value to get the return address.<\/span><\/span><br \/>\n<span style=\"font-size: 14pt;\">The current stack value is CFFD, so 5 places lower than necessary (we used 1 + 1 + 1 byte for the parameters and 2 bytes for the return address):<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 21.77%;\"><span style=\"font-size: 18.6667px;\">LD HL, 5<\/span><\/td>\n<td style=\"width: 78.23%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.77%;\"><span style=\"font-size: 18.6667px;\">ADD HL, SP<\/span><\/td>\n<td style=\"width: 78.23%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.77%;\"><span style=\"font-size: 18.6667px;\">LD SP, HL<\/span><\/td>\n<td style=\"width: 78.23%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\"><span class=\"\">The stack pointer now points to the right position to return to the calling program via\u00a0<\/span><span class=\"\">RET.<\/span><\/span><\/p>\n<p><span style=\"font-size: 14pt;\">The calling program must now collect the result from the stack which after returning from the subroutine points to the address D003.\u00a0The return parameter is 5 bytes below (remember? 1 + 1 + 1 + 2 bytes):<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 21.9193%;\"><span style=\"font-size: 18.6667px;\">LD HL, 5<\/span><\/td>\n<td style=\"width: 78.0807%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.9193%;\"><span style=\"font-size: 18.6667px;\">ADD HL, SP<\/span><\/td>\n<td style=\"width: 78.0807%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.9193%;\"><span style=\"font-size: 18.6667px;\">LD SP, HL<\/span><\/td>\n<td style=\"width: 78.0807%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 21.9193%;\"><span style=\"font-size: 18.6667px;\">POP AF<\/span><\/td>\n<td style=\"width: 78.0807%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">In register A we have the result.<\/span><\/p>\n<h3>Fourth method<\/h3>\n<p><span style=\"font-size: 14pt;\">The passage of parameters in the memory area immediately following the invocation of subroutines, as we have already said, is the one used by the Hitech C compiler.\u00a0When a subroutine is invoked, the return address resides at the bottom of the stack.\u00a0Therefore by executing POP IX the index register points to the memory area where are the parameters to pass.\u00a0Let&#8217;s see an example:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">02F2<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">CALL subr1<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; Call subroutine1<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">02F5<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">Parm1<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; First 8-bit parameter<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">02F6\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">Parm2<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; Second parameter of 16 bits<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">02F7\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 65.8949%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">02F8\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">Parm3<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; Third parameter 16 bit<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">02F9 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 65.8949%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">\u00a0At\u00a0 address 02FA there is the continuation\u00a0\u00a0of\u00a0the calling program.\u00a0Suppose Subr1 is at 0300:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0300\u00a0<\/span>Subr1:<\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">POP IX\u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; IX = 02F5<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0301\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD A,(IX+1)\u00a0\u00a0<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; A = parm2 LSB<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0305\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD E,A<\/span><\/td>\n<td style=\"width: 65.8949%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0306\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD A,(IX+2)<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; A = parm2 MSB<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">030A\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD D,A<\/span><\/td>\n<td style=\"width: 65.8949%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">030B\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD A,(IX+3)<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; A = parm3 LSB<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">030F\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD L,A<\/span><\/td>\n<td style=\"width: 65.8949%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0310\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD A,(IX+4)\u00a0\u00a0<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; A = parm3 MSB<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0313\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD H,A<\/span><\/td>\n<td style=\"width: 65.8949%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.2146%;\"><span style=\"font-size: 18.6667px;\">0314\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 19.8904%;\"><span style=\"font-size: 18.6667px;\">LD A,(IX+0)\u00a0<\/span><\/td>\n<td style=\"width: 65.8949%;\"><span style=\"font-size: 18.6667px;\">; A = parm1<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">The POP IX instruction loads into the index register IX the return address to the program placed by CALL Subr1 on the stack.\u00a0In IX we therefore have an address that does not point to an instruction but to the data block to be passed to the Subr1 subroutine.\u00a0By adding the appropriate offset to IX, we can load the values \u200b\u200bto be passed into the registers.\u00a0After a series of calculations, the Subr1 subroutine returns the result by putting it at the address pointed to by IX plus the appropriate offset.\u00a0Recall that IX still bets 02F5, so we can deposit the return value easily.\u00a0Now let&#8217;s see how to return to the address immediately following the invocation of Subr1:<\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 14.3639%;\"><span style=\"font-size: 18.6667px;\">0320\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 20.0398%;\"><span style=\"font-size: 18.6667px;\">LD BC, 5\u00a0<\/span><\/td>\n<td style=\"width: 65.5962%;\"><span style=\"font-size: 18.6667px;\">; 5 bytes of parameters (2 + 2 + 1)<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.3639%;\"><span style=\"font-size: 18.6667px;\">0323\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 20.0398%;\"><span style=\"font-size: 18.6667px;\">ADD IX, BC\u00a0\u00a0<\/span><\/td>\n<td style=\"width: 65.5962%;\"><span style=\"font-size: 18.6667px;\">; 02F5 + 5 = 02FA<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.3639%;\"><span style=\"font-size: 18.6667px;\">0325\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 20.0398%;\"><span style=\"font-size: 18.6667px;\">PUSH IX\u00a0<\/span><\/td>\n<td style=\"width: 65.5962%;\"><span style=\"font-size: 18.6667px;\">; IX = 02FA<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 14.3639%;\"><span style=\"font-size: 18.6667px;\">0327\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 20.0398%;\"><span style=\"font-size: 18.6667px;\">RET\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 65.5962%;\"><span style=\"font-size: 18.6667px;\">; back to 02FA<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\"><span class=\"\">Recall that IX contains the address of the first parameter, therefore the return address from the subroutine is given by the sum of the latter and the number of bytes occupied by the parameters.\u00a0<\/span>In this case IX is equal to 02F5, the bytes used are 5 so the return address is 02FA then PUSH IX puts the correct address on the stack for the return.\u00a0A simple RET takes us back to the main program flow.<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">The \u201cclean\u201d organization of the parameters pays for itself in terms of machine time, the LD A instruction (IX + offset) costs 5 machine cycles.\u00a0This explains why the code generated by compiling with Hi-tech C is not fast in execution compared to that of other C compilers.<\/span><\/p>\n<p><span style=\"font-size: 14pt;\"><span class=\"\">We have seen that to pass parameters to a function written in assembler Z80, Hi-tech C uses a procedure that\u00a0<\/span><span class=\"\">at first sight may seem complex but very efficient.<\/span><\/span><\/p>\n<p><span style=\"font-size: 14pt;\">When an assembler function is invoked by the C language program, the arguments are pushed onto the stack in reverse order, that is, the first argument is in the lowest memory address.\u00a0The same happens for a C language routine invoked by an assembler program.<\/span><br \/>\n<span style=\"font-size: 14pt;\"><span class=\"\">In the case of a single floating point parameter, the structure is the modified IEEE754P one:<\/span><\/span><\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 13.3549%;\"><span style=\"font-size: 18.6667px;\">sign\u00a0 \u00a0 \u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 86.6451%;\"><span style=\"font-size: 18.6667px;\">1 bit<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 13.3549%;\"><span style=\"font-size: 18.6667px;\">exponent\u00a0 \u00a0<\/span><\/td>\n<td style=\"width: 86.6451%;\"><span style=\"font-size: 18.6667px;\">7 bit<\/span><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 13.3549%;\"><span style=\"font-size: 18.6667px;\">mantissa\u00a0 \u00a0\u00a0<\/span><\/td>\n<td style=\"width: 86.6451%;\"><span style=\"font-size: 18.6667px;\">24 bit normalized<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 14pt;\">The number is stored with the sign in the bit7 of the highest byte and the mantissa in the lowest byte.<\/span><br \/>\n<span style=\"font-size: 14pt;\">To read the parameter we need to use the updated IX pointer with the stack pointer plus some offset.<\/span><br \/>\n<span style=\"font-size: 14pt;\">The offset, with respect to the stack pointer, to be adopted is 6 due to 2 bytes for the return address, 2 bytes for IX\u00a0and another 2 bytes for the first PUSH that saves the IX index:<\/span><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npsect text, global\r\nglobal _programma, prg1, prg2\r\n\r\narg equ 6        ; offset to first argument\r\n_programma:\r\npush iy          ; procedure reading input parameters\r\npush ix\r\nld ix,0\r\nadd ix,sp        ; IX points to first argument\r\n\r\nld a, 00h        ;\r\nld (flagz), a    ; flagz contains 0\r\n\r\n; copy first argument in HL DE\r\nld e,(ix+arg+0)  ; low byte mantissa\r\nld d,(ix+arg+1)  ; middle byte mantissa\r\nld l,(ix+arg+2)  ; high byte mantissa\r\nld h,(ix+arg+3)  ; sign + exponent\r\n\r\n....\r\n\r\nld sp,ix         ; procedure of exit\r\npop ix\r\npop iy\r\nret\r\n\r\n<\/pre>\n<p><span style=\"font-size: 14pt;\">The return of the processing result is in HL DE.<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">In the case of word type, the value returns in HL;\u00a0a long word in HL DE with the top in HL.\u00a0The integers are in L and the sign in H.<\/span><br \/>\n<span style=\"font-size: 14pt;\">The character pointers occupy 2 bytes and are loaded in HL, for example we see a module\u00a0receiving a character pointer where it writes &#8216;0&#8217;, &#8216;1&#8217;, the string terminator &#8216;\\ 0&#8217; and returns\u00a0the pointer to the received vector in HL:<\/span><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\npsect text, global\r\nglobal _stringa, prg1, prg2\r\n\r\narg equ 6       ; offset to first argument\r\npush iy         ; procedure reading input parameters\r\npush ix\r\nld ix,0\r\nadd ix,sp       ; pointer to arguments\r\n                ; in HL the address to the pointer\r\nld l,(ix+arg+0) ; high byte of the address\r\nld h,(ix+arg+1) ; low byte of the address\r\nld (hl), 48     ; '0'\r\ninc hl\r\nld (hl), 49     ; '1'\r\ninc hl\r\nld (hl), 0      ; string terminator\r\ndec hl          ; many dec hl for each element of the vector excluding the terminator\r\ndec hl          ; HL points to the first element of the vector\r\nld sp,ix        ; then exit\r\npop ix\r\npop iy\r\nret\r\n<\/pre>\n<p><span style=\"font-size: 14pt;\">Now let&#8217;s see an example in Z80 assembler language that takes up the FMOD library function published in LIBV.<\/span><\/p>\n<p><span style=\"font-size: 14pt;\">In this module you can see in practice how parameters are passed between the various modules, how to invoke existing library modules and how to receive data and return the result.\u00a0<span class=\"\">The compilation is done with the command ZAS FMOD.Z80, the generated obj file is added to the library with LIBR R LIBV.LIB FMOD.OBJ<\/span><\/span><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n; double fmod(double z, double x)\r\n; ritorna il resto della divisione di z per x, entrambi floating point\r\n;\r\n; fmod(z,x) = z - x * floor(z\/x)\r\n; se x&gt;0 allora (0 &lt;= fmod(z,x) &lt;= x)\r\n; se x&lt;=0 allora (-x &lt;= fmod(z,x) &lt;= 0)\r\n;\r\n; Formato di un numero floating point\r\n; ------------\r\n; * segno     * 1 bit\r\n; *-----------*\r\n; * esponente * 7 bit\r\n; *-----------*\r\n; * mantissa  * 24 bit normalizzato\r\n; -------------\r\n; Il numero e' memorizzato con il segno nel byte piu' alto e\r\n; la mantissa nel byte piu' basso\r\n\r\npsect text, global\r\nglobal _fmod, _floor, flsub, flmul, fldiv, fladd\r\n\r\narg equ 6             ; offeset primo argomento\r\n\r\n_fmod:\r\n      ex (sp), iy     ; salva IY per l'indirizzo di ritorno\r\n      push ix\r\n      ld ix, 0\r\n      add ix, sp      ; in IX il puntatore ai parametri\r\n      ld l,(ix+arg+4) ; salva x in HL DE\r\n      ld h,(ix+arg+5) ; segno ed esponente in H\r\n      ld e,(ix+arg+6) ; in L e DE la mantissa\r\n      ld d,(ix+arg+7) ;\r\n      push hl         ; salva x nello stack\r\n      push de         ;\r\n\r\n      ld l,(ix+arg+0) ; salva z in HL DE\r\n      ld h,(ix+arg+1) ; segno ed esponente in H\r\n      ld e,(ix+arg+2) ; in L e DE la mantissa\r\n      ld d,(ix+arg+3) ;\r\n                      ; abbiamo x (4 byte) nello stack\r\n                      ; z in HL DE\r\n\r\n; Divisione float di libreria. Il numero in HL DE e' diviso\r\n; con il numero che risiede nello stack sotto all'indirizzo\r\n; di ritorno.\r\n; Lo stack e' pulito e il risultato torna in HL DE.\r\n; Vedere il sorgente round in float.as\r\n; ( z \/ x )\r\n\r\n      call fldiv      ; divide HL DE per \r\n                      ; HL DE salvato nello stack\r\n                      ; risultato in HL DE\r\n      exx             ; aggiusta lo stack\r\n      pop de\r\n      pop hl\r\n      exx\r\n\r\n; Arrotonda il numero in HL DE all'unita' superiore\r\n; con lo shift di bit\r\n; floor.c e' in libf.lib\r\n; floor( z \/ x )\r\n\r\n      call _floor\r\n\r\n; Moltiplicazione floating point. Il numero in HL DE e'\r\n; moltiplicato con il numero che risiede nello stack sotto\r\n; all'indirizzo di ritorno.\r\n; Lo stack e' pulito e il risultato torna in HL DE.\r\n; Vedere il sorgente in flmul in float.as\r\n; x * floor( z \/ x )\r\n      push hl         ; salva floor(z\/x)\r\n      push de         ; nello stack\r\n\r\n; recupera x\r\n      ld l,(ix+arg+4) ; salva x in HL DE\r\n      ld h,(ix+arg+5) ; segno ed esponente in H\r\n      ld e,(ix+arg+6) ; in L e DE la mantissa\r\n      ld d,(ix+arg+7) ;\r\n\r\n      call flmul      ; moltiplica HL DE per \r\n                      ; HL DE salvato nello stack\r\n                      ; risultato in HL DE\r\n\r\n      exx             ; aggiusta lo stack\r\n      pop de\r\n      pop hl\r\n      exx\r\n\r\n; Sottrazione floating point. Il valore nello stack\r\n; e' sottratto da HL DE: z - x = z + (-x)\r\n; Vedere il sorgente in flsub in float.as\r\n; z - x * floor( z \/ x )\r\n\r\n      call flsub      ; sottrae da HL DE il valore\r\n                      ; HL DE salvato nello stack \r\n                      ; risultato in HL DE\r\n      ld sp,ix\r\n      pop iy\r\n      ret\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_240\" class=\"pvc_stats all  \" data-element-id=\"240\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/automatico.freevar.com\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>One of the phases of invoking a subroutine, in assembler language, is the passing of parameters. There are four common methods for passing parameters: through the machine registers; storage of the values \u200b\u200bin a predetermined memory area; via stack; writing data to the memory area immediately following the subroutine call. Of these four modes, the [&hellip;]<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_240\" class=\"pvc_stats all  \" data-element-id=\"240\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/automatico.freevar.com\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"parent":54,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-240","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/pages\/240"}],"collection":[{"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/comments?post=240"}],"version-history":[{"count":29,"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/pages\/240\/revisions"}],"predecessor-version":[{"id":774,"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/pages\/240\/revisions\/774"}],"up":[{"embeddable":true,"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/pages\/54"}],"wp:attachment":[{"href":"https:\/\/automatico.freevar.com\/index.php\/wp-json\/wp\/v2\/media?parent=240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}