Code Generation/Exercise 14

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 mop(double v[], int s) {
  int p = 0;
  double m = 0;
  for (int i = 0; i < s; ++i) {
    if (v[i] > 0) {
      m = m + v[i];
      ++p;
    }
  }
  return p ? m / p : 0;
}

Código Postfix (não optimizado)

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

Código Postfix
TEXT
LABEL mop
ENTER 16 ; p@-4 m@-12 i@-16 v@+8 s@+12

INT 0
LOCAL -4
STINT ; p

INT 0
I2D
LOCAL -12
STDOUBLE ; m

INT 0
LOCAL -16
STINT ; i

LABEL fortest
LOCAL -16
LDINT ; i
LOCAL 12
LDINT ; s
LT
JZ forend

LOCAL 8
LDINT ; v
LOCAL -16
LDINT ; i
INT 8
MUL
ADD ; &v[i]
LDDOUBLE ; v[i]

INT 0
I2D

DCMP
INT 0
GT ; v[i] > 0
JZ ifend

LOCAL -12
LDDOUBLE ; m
LOCAL 8
LDINT ; v
LOCAL -16
LDINT ; i
INT 8
MUL
ADD ; &v[i]
LDDOUBLE ; v[i]

DADD
DUP64

LOCAL -12
STDOUBLE ; m = ...

TRASH 8

LOCAL -4
LDINT ; p
INT 1
ADD
DUP32
LOCAL -4
STINT
TRASH 4

LABEL ifend

LABEL forincr
LOCAL -16
LDINT
INT 1
ADD
DUP32
LOCAL -16
STINT
TRASH 4
JMP fortest
LABEL forend

LOCAL -4
LDINT ; p
JZ op3else
LOCAL -12
LDDOUBLE ; m
LOCAL -4
LDINT
I2D
DDIV
JMP op3end
LABEL op3else
INT 0
I2D
LABEL op3end

STFVAL64
LEAVE
RET

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