(→Compiling and Running) |
(→Function "mkvec") |
||
Line 59: | Line 59: | ||
LABEL mkvec | LABEL mkvec | ||
ENTER 8 ; s@-4 v@-8 | ENTER 8 ; s@-4 v@-8 | ||
− | + | LOCAL 8 | |
+ | LOAD | ||
INT 1 | INT 1 | ||
LT | LT | ||
Line 76: | Line 77: | ||
LABEL ifend1 | LABEL ifend1 | ||
INT 8 ; sizeof(double) | INT 8 ; sizeof(double) | ||
− | + | LOCAL -4 | |
− | + | STORE | |
− | + | LOCAL +8 | |
+ | LOAD | ||
+ | LOCAL -4 | ||
+ | LOAD | ||
MUL | MUL | ||
CALL malloc | CALL malloc | ||
Line 86: | Line 90: | ||
TRASH 4 | TRASH 4 | ||
PUSH | PUSH | ||
− | + | LOCAL -8 | |
− | + | STORE | |
+ | LOCAL -8 | ||
+ | LOAD | ||
POP | POP | ||
LEAVE | LEAVE |
Consider the following C code and assume that the size of pointers, int, and unsigned long is 32 bits and that the size of double is 64 bits.
<c> static unsigned long a = 10; static double *v; extern void *malloc(unsigned long);
static double *mkvec(unsigned long n) {
if (n < 1) return (double *)0; unsigned long s = sizeof(double); double *v = (double *)malloc(n * s); return v;
}
double *compute() {
v = mkvec(a * 4); for (unsigned long i = 1; i < a; i++) if (v[i] > v[0]) v[i] = 3 * i - 1; return v;
} </c>
The Postfix code for the above code is as follows: (code has not been thoroughly checked: bug reports are welcome)
In the following code sections, BB# means "basic block number".
<asm>
DATA ALIGN LABEL a CONST 10
DATA ; "static" variables are always initialized ALIGN LABEL v CONST 0 ; this is a null pointer </asm>
<asm> EXTERN malloc </asm>
<asm>
TEXT ALIGN LABEL mkvec ENTER 8 ; s@-4 v@-8 LOCAL 8 LOAD INT 1 LT JZ ifend1
INT 0 POP LEAVE RET
ALIGN LABEL ifend1 INT 8 ; sizeof(double) LOCAL -4 STORE LOCAL +8 LOAD LOCAL -4 LOAD MUL CALL malloc
TRASH 4 PUSH LOCAL -8 STORE LOCAL -8 LOAD POP LEAVE RET
</asm>
<asm>
TEXT ALIGN GLOBAL compute, FUNC LABEL compute ENTER 4 ; i@-4 ADDRV a INT 4 MUL CALL mkvec
TRASH 4 PUSH DUP ADDRA v TRASH 4 INT 1 LOCA -4
ALIGN LABEL fortest LOCV -4 ADDRV a LT JZ forend
ADDRV v LOCV -4 INT 8 MUL ADD DLOAD ADDRV v INT 0 INT 8 MUL ADD DLOAD DCMP INT 0 GT JZ ifend2
INT 3 LOCV -4 MUL INT 1 SUB I2D DDUP ADDRV v LOCV -4 INT 8 MUL ADD DSTORE TRASH 8
ALIGN LABEL ifend2 ALIGN LABEL forincr LOCV -4 DUP INT 1 ADD LOCA -4 TRASH 4 JMP fortest
ALIGN LABEL forend ADDRV v POP LEAVE RET
</asm>
To compile the Postfix code directly, pf2asm can be used (assuming a 32-bit architecture):
pf2asm compute.pf yasm -felf compute.asm