|
|
Line 1: |
Line 1: |
| {{TOCright}}
| | #REDIRECT [[ist:Code Generation/Exercise 11]] |
| == Problema ==
| |
| | |
| Considere o seguinte código C++ (assuma que ponteiros e '''int''' ocupam 32 bits e que '''double''' ocupa 64 bits).
| |
| | |
| <cpp>
| |
| double *forall(double *v) {
| |
| const static int limit = 1024;
| |
| for (int i = 0; i < limit; i++) {
| |
| v[i] = 3 * i – sizeof(double);
| |
| if (v[i] > 2 * i) v[i] = limit;
| |
| }
| |
| return v;
| |
| }
| |
| </cpp>
| |
| | |
| == Código Postfix (não optimizado) ==
| |
| | |
| O código Postfix correspondente à função é o seguinte (agradece-se a comunicação de questões relativas a este código).
| |
| | |
| No código Postfix, '''BB#''' significa "[[Optimization Topics|bloco básico]] número".
| |
| {{CollapsedCode|Postfix code|
| |
| <asm>
| |
| TEXT
| |
| ALIGN
| |
| GLOBAL forall, FUNC
| |
| LABEL forall
| |
| ENTER 4 ; i@-4 v@+8
| |
| | |
| ; define "limit" (this is not an assignment)
| |
| RODATA
| |
| ALIGN
| |
| LABEL limit ; not really this name
| |
| SINT 1024
| |
| ; done - go back to code segment
| |
| TEXT
| |
| ALIGN
| |
| | |
| ; initialize for-loop control variable (again, not an assignment)
| |
| INT 0
| |
| LOCAL -4
| |
| STINT ; i = 0
| |
| | |
| ; for-loop test
| |
| LABEL fortest
| |
| LOCAL -4
| |
| LDINT ; i
| |
| ADDR limit
| |
| LDINT ; limit
| |
| LT ; i<limit
| |
| JZ forend
| |
| | |
| ; BEGIN for-loop body
| |
| | |
| ; BEGIN assignment to v[i]
| |
| | |
| ; compute and promote 3*i
| |
| INT 3
| |
| LOCAL -4 ; &i
| |
| LDINT ; i
| |
| MUL
| |
| INT 8 ; sizeof(double)
| |
| SUB
| |
| I2D
| |
| | |
| DUP64 ; implement assignment value
| |
| | |
| ; compute &v[i] == v+i*sizeof(double)
| |
| LOCAL +8 ; &v
| |
| LDINT ; v
| |
| LOCAL -4 ; &i
| |
| LDINT ; i
| |
| INT 8 ; sizeof(double)
| |
| MUL
| |
| ADD ; &v[i]
| |
| | |
| STDOUBLE ; do assignment of double value
| |
| | |
| TRASH 8 ; discard value of assignment
| |
| | |
| ; END assignment to v[i]
| |
| | |
| ; if condition
| |
| ; compute &v[i] == v+i*sizeof(double)
| |
| LOCAL +8 ; &v
| |
| LDINT ; v
| |
| LOCAL -4 ; &i
| |
| LDINT ; i
| |
| INT 8 ; sizeof(double)
| |
| MUL
| |
| ADD ; &v[i]
| |
| LDDOUBLE ; v[i]
| |
| | |
| ; compute and promote 2*i
| |
| INT 2
| |
| LOCAL -4 ; &i
| |
| LDINT ; i
| |
| MUL
| |
| I2D
| |
| | |
| ; compare
| |
| DCMP
| |
| INT 0
| |
| GT
| |
| | |
| ; jump to if end
| |
| JZ ifend
| |
| | |
| ; BEGIN if block
| |
| ; do assignment (double)
| |
| | |
| ; load and promote "limit"
| |
| ADDR limit
| |
| LDINT
| |
| I2D
| |
| | |
| DDUP ; implement assignment value
| |
| | |
| ; compute &v[i] == v+i*sizeof(double)
| |
| LOCAL +8 ; &v
| |
| LDINT ; v
| |
| LOCAL -4 ; &i
| |
| LDINT ; i
| |
| INT 8 ; sizeof(double)
| |
| MUL
| |
| ADD ; &v[i]
| |
| | |
| STDOUBLE ; do assignment of double value
| |
| | |
| TRASH 8 ; discard value of assignment
| |
| | |
| ; END if block
| |
| LABEL ifend
| |
| | |
| ; FOR increment
| |
| LABEL forincr
| |
| | |
| ; increment expression
| |
| LOCAL -4 ; &i
| |
| LDINT ; i
| |
| DUP32
| |
| INT 1
| |
| ADD
| |
| LOCAL -4 ; &i
| |
| STINT
| |
| TRASH 4
| |
| | |
| ; END for-loop body
| |
| JMP fortest
| |
| LABEL forend
| |
| | |
| ; return *v
| |
| LOCAL +8 ; &v
| |
| LDINT ; v
| |
| STFVAL32
| |
| LEAVE
| |
| RET
| |
| | |
| </asm>
| |
| }}
| |
| | |
| == Compiling and Running ==
| |
| | |
| Para compilar o código Postfix directamente, pode ser utilizada a ferramenta [[pf2asm]] (assumindo uma arquitectura de 32 bits):
| |
| | |
| pf2asm forall.pf
| |
| yasm -felf forall.asm
| |
| | |
| [[category:Compiladores]]
| |
| [[category:Ensino]]
| |