Difference between revisions of "Code Generation/Exercise 7"

From Wiki**3

< Code Generation
(Created page with "== The Original Code == Consider the following C function: <c> int *traverse(int vec[], int lim) { int *ptr = vec + lim - 1, ix = lim - 2; while (ix >= 0) { ptr = (vec[...")
 
(Compiling and Running)
 
(7 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
Consider the following C function:
 
Consider the following C function:
  
<c>
+
<source lang="c">
 
int *traverse(int vec[], int lim) {
 
int *traverse(int vec[], int lim) {
 
   int *ptr = vec + lim - 1, ix = lim - 2;
 
   int *ptr = vec + lim - 1, ix = lim - 2;
Line 12: Line 12:
 
   return ptr;
 
   return ptr;
 
}
 
}
</c>
+
</source>
  
 
== Postfix Code ==
 
== Postfix Code ==
  
 
The Postfix code for the above function is as follows:  
 
The Postfix code for the above function is as follows:  
 
+
{{CollapsedCode|Postfix code|
<asm>
+
<source lang="asm">
 
TEXT
 
TEXT
 
ALIGN
 
ALIGN
Line 26: Line 26:
  
 
; init prt (not assignment)
 
; init prt (not assignment)
LOCV +8  ; vec
+
LOCAL +8
LOCV +12 ; lim
+
LDINT ; vec
 +
LOCAL +12
 +
LDINT ; lim
 
INT 4    ; sizeof int
 
INT 4    ; sizeof int
 
MUL
 
MUL
Line 35: Line 37:
 
MUL
 
MUL
 
SUB      ; vec + lim - 1
 
SUB      ; vec + lim - 1
LOCA -4  ; ptr = vec + lim - 1
+
LOCAL -4
 +
STINT ; ptr = vec + lim - 1
  
 
; init ix (not assignment)
 
; init ix (not assignment)
LOCV +12 ; lim
+
LOCAL +12
 +
LDINT ; lim
 
INT 2
 
INT 2
 
SUB
 
SUB
LOCA -8  ; ix = lim -2
+
LOCAL -8
 +
STINT ; ix = lim -2
  
 
; while start: test
 
; while start: test
 
ALIGN
 
ALIGN
 
LABEL while_test
 
LABEL while_test
LOCV -8
+
LOCAL -8
 +
LDINT
 
INT 0
 
INT 0
 
GE      ; ix >= 0
 
GE      ; ix >= 0
Line 54: Line 60:
  
 
; ?: operator
 
; ?: operator
LOCV +8  ; vec
+
LOCAL +8
LOCV -8  ; ix
+
LDINT ; vec
 +
LOCAL -8
 +
LDINT ; ix
 
INT 4    ; sizeof int
 
INT 4    ; sizeof int
 
MUL
 
MUL
 
ADD      ; vec + ix
 
ADD      ; vec + ix
LOAD     ; *(vec+ix) --> vec[ix]
+
LDINT     ; *(vec+ix) --> vec[ix]
  
LOCV -4  ; ptr
+
LOCAL -4
LOAD    ; *ptr
+
LDINT ; ptr
 +
LDINT  ; *ptr
  
 
GT
 
GT
Line 68: Line 77:
  
 
; ?: true part
 
; ?: true part
LOCV +8  ; vec
+
LOCAL +8
LOCV -8  ; ix
+
LDINT ; vec
 +
LOCAL -8
 +
LDINT ; ix
 
INT 4    ; sizeof int
 
INT 4    ; sizeof int
 
MUL
 
MUL
Line 77: Line 88:
  
 
; ?: false part
 
; ?: false part
LOCV -4  ; ptr
+
ALIGN
 +
LABEL three_false_part
 +
 
 +
LOCAL -4
 +
LDINT ; ptr
  
 
; ?: end
 
; ?: end
Line 83: Line 98:
 
LABEL three_end
 
LABEL three_end
  
DUP     ; for assignment
+
DUP32     ; for assignment
LOCA -4  ; ptr = ?: ...
+
LOCAL -4
 +
STINT ; ptr = ?: ...
  
 
; trash expression value (used as instruction)
 
; trash expression value (used as instruction)
Line 90: Line 106:
  
 
; decrement ix
 
; decrement ix
LOCV -8  ; ix
+
LOCAL -8
DUP
+
LDINT ; ix
 +
DUP32
 
INT 1
 
INT 1
 
SUB
 
SUB
LOCA -8  ; ix = ix - 1
+
LOCAL -8
 +
STINT ; ix = ix - 1
 
TRASH 4  ; (ix-- used as instruction)
 
TRASH 4  ; (ix-- used as instruction)
  
Line 105: Line 123:
  
 
; return ptr
 
; return ptr
LOCV -4
+
LOCAL -4
POP
+
LDINT
 +
STFVAL32
 
LEAVE
 
LEAVE
 
RET
 
RET
</asm>
+
</source>
 +
}}
  
 
== Compiling and Running ==
 
== Compiling and Running ==
  
To compile the Postfix code directly, [[pf2asm]] can be used:
+
To compile the Postfix code directly, [[Compiladores/Projecto de Compiladores/Compiladores Exemplo|pf2asm]] can be used:
  
* pf2asm traverse.pf
+
pf2asm traverse.pf
* yasm -felf traverse.asm
+
yasm -felf traverse.asm
  
[[category:Compilers]]
+
[[category:Compiladores]]
[[category:Teaching]]
+
[[category:Ensino]]

Latest revision as of 18:51, 6 May 2019

The Original Code

Consider the following C function:

int *traverse(int vec[], int lim) {
  int *ptr = vec + lim - 1, ix = lim - 2;
  while (ix >= 0) {
    ptr = (vec[ix] > *ptr) ? vec + ix : ptr;
    ix--;
  }
  return ptr;
}

Postfix Code

The Postfix code for the above function is as follows:

Postfix code
TEXT
ALIGN
GLOBL traverse, FUNC
LABEL traverse
ENTER 8  ; ptr@-4 ix@-8 vec@+8 lim@+12

; init prt (not assignment)
LOCAL +8
LDINT  ; vec
LOCAL +12
LDINT ; lim
INT 4    ; sizeof int
MUL
ADD      ; vec + lim
INT 1
INT 4    ; sizeof int
MUL
SUB      ; vec + lim - 1
LOCAL -4
STINT  ; ptr = vec + lim - 1

; init ix (not assignment)
LOCAL +12
LDINT ; lim
INT 2
SUB
LOCAL -8
STINT  ; ix = lim -2

; while start: test
ALIGN
LABEL while_test
LOCAL -8
LDINT
INT 0
GE       ; ix >= 0
JZ while_end

; while block

; ?: operator
LOCAL +8
LDINT  ; vec
LOCAL -8
LDINT  ; ix
INT 4    ; sizeof int
MUL
ADD      ; vec + ix
LDINT     ; *(vec+ix) --> vec[ix]

LOCAL -4
LDINT  ; ptr
LDINT  ; *ptr

GT
JZ three_false_part

; ?: true part
LOCAL +8
LDINT  ; vec
LOCAL -8
LDINT  ; ix
INT 4    ; sizeof int
MUL
ADD      ; vec + ix

JMP three_end

; ?: false part
ALIGN
LABEL three_false_part

LOCAL -4
LDINT  ; ptr

; ?: end
ALIGN
LABEL three_end

DUP32      ; for assignment
LOCAL -4
STINT  ; ptr = ?: ...

; trash expression value (used as instruction)
TRASH 4

; decrement ix
LOCAL -8
LDINT  ; ix
DUP32
INT 1
SUB
LOCAL -8
STINT  ; ix = ix - 1
TRASH 4  ; (ix-- used as instruction)

; end while block
JMP while_test

; exit while cycle
ALIGN
LABEL while_end

; return ptr
LOCAL -4
LDINT
STFVAL32
LEAVE
RET

Compiling and Running

To compile the Postfix code directly, pf2asm can be used:

pf2asm traverse.pf
yasm -felf traverse.asm