Code Generation/Exercise 12

From Wiki**3

< Code Generation

Problema

Considere o seguinte código C++ (assuma que ponteiros e int ocupam 32 bits e que double ocupa 64 bits).

static double v[] = { 1.41, 2.71, 3.14 };
int f(double v[], int s, double d) {
  for (int i = 0; i < s; i++)
    if (v[i] == d) return i;
  return -1;
}
int main() {
  return f(v, 3, 3.14);
}

Código Postfix (não optimizado)

O código Postfix correspondente às funções é o seguinte (agradece-se a comunicação de questões relativas a este código).

No código Postfix, BB# significa "bloco básico número".

Vector "v"
;; static double v[] = { 1.41, 2.72, 3.14 };
;;
DATA
ALIGN
LABEL v          ; v is a vector
SDOUBLE 1.41
SDOUBLE 2.72
SDOUBLE 3.14
Função "f"
;; function "f"
;;

;;--- BB1 --- begin ---
TEXT
ALIGN
GLOBAL f, FUNC
LABEL  f
ENTER 4  ; i@-4, v@+8, s@+12, d@+16

;; BEGIN -- for

INT 0
LOCA -4  ; int i = 0

;;--- BB1 --- end ---
;;--- BB2 --- begin ---

LABEL for_test

LOCAL -4       ; &i
LDINT           ; i
LOCAL +12      ; &s
LDINT           ; s
LT             ; i < s

JZ for_end

;;--- BB2 --- end ---
;;--- BB3 --- begin ---

;; BEGIN -- for body

LOCAL +8       ; &v
LDINT           ; v (v is a pointer)
LOCAL -4       ; &i
LDINT           ; i
INT 8          ; sizeof(double)
MUL
ADD            ; v+i == &v[i]
LDDOUBLE          ; v[i]

LOCAL +16      ; &d
LDDOUBLE          ; d

DCMP
INT 0
EQ             ; v[i] == d

JZ if_end

;;--- BB3 --- end ---
;;--- BB4 --- begin ---

;; BEGIN -- if body

LOCAL -4       ; &i
LDINT           ; i

STFVAL32
LEAVE
RET

;; end -- if body

;;--- BB4 --- end ---
;;--- BB5 --- begin ---

LABEL if_end

;; END -- for body

LABEL for_incr

LOCAL -4      ; &i
LDINT          ; i
DUP32           ; i
INT 1
ADD           ; i+1
LOCAL -4      ; &i
STINT         ; i = i + 1
TRASH 4

JMP for_test
;; END -- for

;;--- BB5 --- end ---
;;--- BB6 --- begin ---

LABEL for_end

INT -1
STFVAL32
LEAVE
RET

;;--- BB6 --- end ---
Função principal
;; main function
;;

;;--- BB7 --- begin ---

TEXT
ALIGN
GLOBAL _main, FUNC
LABEL _main
START      ; no local vars

RODATA
ALIGN
LABEL _L314
SDOUBLE 3.14
TEXT
ADDR _L314
LDDOUBLE      ; 3.14

INT 3

ADDR v     ; v == &v (v is a vector)

CALL f
;;--- BB7 --- end ---

;;--- BB8 --- begin ---
TRASH 16

LDFVAL32
STFVAL32
LEAVE
RET

;;--- BB8 --- end ---

Compiling and Running

Para compilar o código Postfix directamente, pode ser utilizada a ferramenta pf2asm (assumindo uma arquitectura de 32 bits):

pf2asm code.pf
yasm -felf32 code.asm

Para criar o executável:

ld -m elf_i386 -o code code.o -L$HOME/compiladores/root/usr/lib -lrts

Para executar o programa:

./code

Para aferir o resultado (retorno do programa ao shell -- zsh/bash assumidos como exemplos):

echo $?