目录
数组



三维数组
LOC(A[i,j,k])=base+(((i-low1)*n2+j-low2)*n3+k-low3)*w
=((i*n2+j)*n3+k)*w+base-((low1*n2+low2)*n3+low3)*w

数组 A
是一个三维数组,维度为 n1 × n2 × n3
,low1、low2、low3,每个元素占 w
个字节空间,基地址为 A
(常量)
数组 B
是一个二维数组,维度为 m1 × m2
,low1、low2、low3,每个元素占 w
个字节空间(与 A
相同),基地址为 B
(常量)
C_A = base_A - ((low1_A×n2 + low2_A)×n3 + low3_A)×w
C_B = base_B - (low1_B×m2 + low2_B)×w
-
计算
A[x][y][z]
的地址并加载其值。 -
计算
B[i][j]
的地址并存储加载的值。
// 计算 A[x][y][z] 的值
T1 = x * n2 (1)(*,x,n2,T1)
T1 = T1 + y (2)(+,T1,y,T1)
T2 = T1 * n3 (3)(*,T1,n3,T2)
T2 = T2 + z (4)(+,T2,z,T2)
T3=A - C_A (5)(-,A,C_A,T3)
T4=T2 * w (6)(*,T2,w,T4)
T5=T3[T4] (7)(=[ ],T3,T4,T5)
// 计算 B[i][j] 的地址并存储
T6 = i * m2 (8)(*,i,m2,T6)
T6 = T6 + j (9)(+,T6,j,T6)
T7=B - C_B (10)(-,B,C_B,T7)
T8=T6 * w (11)(*,T6,w,T8)
T7[T8]=T5 (12)([ ]=,T5,T7,T8)
四元式设计:
-
(=[], base, offset, result)
:加载操作,等价于result = *(base + offset)
-
([]=, value, base, offset)
:存储操作,等价于*(base + offset) = value
-
常量
C_A
和C_B
在编译时计算,作为常量操作数使用
if




if(a>b and c>d) x=x+1;
else x=x-1;
三地址码
// 检查第一个条件 a>b
if a > b goto L1
goto E.false // 第一个条件不满足,直接跳转到 false 分支
// 检查第二个条件 c>d
L1: if c > d goto E.true
goto E.false // 第二个条件不满足,跳转到 false 分支
// true 分支
E.true: x=x+1;
goto E.next // 跳过 false 分支
// false 分支
E.false: x=x-1;
goto E.next // 可省略,因为 E.next 紧接其后
// 后续代码
E.next:
四元式
100 (j>, a, b, 102) // 检查 a>b,成立则跳转到 L1 (102)
101 (j, _, _, 107) // 否则跳转到 E.false (107)
// L1 标签位置 (102)
102 (j>, c, d, 104) // 检查 c>d,成立则跳转到 E.true (104)
103 (j, _, _, 107) // 否则跳转到 E.false (107)
// E.true 分支
104 (+, x, 1, T1) // 计算 x+1
105 (=, T1, _, x) // x = x+1
106 (j, _, _, 109) // 跳转到 E.next (109)
// E.false 分支
107 (-, x, 1, T2) // 计算 x-1
108 (=, T2, _, x) // x = x-1
// E.next 标签位置 (109)
109

while




while、if、数组
while (a > b or c > d) {
if (x == 0)
y = A[i][j];
else
y = A[i][k];
}
-
数组
A
是二维数组,维度为n1 × n2
,索引从low1
和low2
开始 -
每个元素占
w
个字节,基地址为A
-
常量
C_A = A - (low1 * n2 + low2) * w
(编译时计算) -
变量
a, b, c, d, x, i, j, k
已定义
三地址码
//while条件检查
LE: if a>b goto E.true
goto L
L: if c>d goto E.true
goto E.false
E.true: if x==0 goto F.true
goto F.false
F.true: T1=i*n2
T1=T1+j
T2=A-C_A
T3=T1*w
y=T2[T3]
goto F.next
F.false: T4-=i*n2
T4=T4+k
T5=A-C_A
T6=T4*w
y=T5[T6]
goto F.next
F.next:
goto LE
E.false:
四元式
100 (j>, a, b, 104) // if a>b 成立,跳转到 E.true (104)
101 (j, _, _, 102) // 否则跳转到 L (102)
102 (j>, c, d, 104) // if c>d 成立,跳转到 E.true (104)
103 (j, _, _, 118) // 否则跳转到 E.false (118)
104 (j==, x, 0, 106) // if x==0 成立,跳转到 F.true (106)
105 (j, _, _, 110) // 否则跳转到 F.false (110)
106 (*, i, n2, T1) // F.true: T1 = i*n2
107 (+, T1, j, T1) // T1 = T1 + j
108 (*, T1, w, T3) // T3 = T1*w (字节偏移)
109 (=[], T2, T3, y) // y = T2[T3] (加载 A[i][j])
110 (j, _, _, 114) // 跳转到 F.next (114)
111 (*, i, n2, T4) // F.false: T4 = i*n2 (注意:这里应该是 111)
112 (+, T4, k, T4) // T4 = T4 + k
113 (*, T4, w, T6) // T6 = T4*w (字节偏移)
114 (=[], T5, T6, y) // y = T5[T6] (加载 A[i][k])
115 (j, _, _, 100) // F.next: 跳回 LE (100)
118 E.false: // 循环结束
优化
基地址计算
T_base = A - C_A
应该提到E.true
前这样可以避免在两个分支中重复计算
// 优化后的四元式序列
100 (j>, a, b, 104) // if a>b
101 (j, _, _, 102) // else
102 (j>, c, d, 104) // if c>d
103 (j, _, _, 118) // else
104 (-, A, C_A, T_base) // E.true: 基地址计算 (提到这里!)
105 (j==, x, 0, 107) // if x==0
106 (j, _, _, 111) // else
107 (*, i, n2, T1) // F.true: T1 = i*n2
108 (+, T1, j, T1) // T1 += j
109 (*, T1, w, T_offset) // T_offset = T1*w
110 (=[], T_base, T_offset, y) // y = T_base[T_offset]
111 (j, _, _, 115) // 跳转到 F.next
112 (*, i, n2, T4) // F.false: T4 = i*n2 (112)
113 (+, T4, k, T4) // T4 += k
114 (*, T4, w, T_offset) // T_offset = T4*w
115 (=[], T_base, T_offset, y) // y = T_base[T_offset] (115)
116 (j, _, _, 100) // F.next: 跳回 LE
118 E.false: // 循环结束
while (a > b or c > d) {
if (x == 0) {
y = A[i][j] * 2;
z = B[k][m] + 1;
} else {
y = A[i][k] / 3;
z = B[k][n] - 1;
}
a = a - 1;
}
-
数组 A 是二维数组,维度为 n1A × n2A,下界为 low1A, low2A
-
数组 B 是二维数组,维度为 n1B × n2B,下界为 low1B, low2B
-
每个元素占 w 个字节
-
常量:
-
C_A = (low1A * n2A + low2A) * w
-
C_B = (low1B * n2B + low2B) * w
-
-
变量 a, b, c, d, x, i, j, k, m, n, y, z 已定义
// While 条件检查 (a > b or c > d)
LE:
if a > b goto E.true
goto L1
L1:
if c > d goto E.true
goto E.false
// 循环体开始
E.true:
T_baseA = A - C_A // 数组 A 的基地址
T_baseB = B - C_B // 数组 B 的基地址
if x == 0 goto F.true
goto F.false
// if true 分支
F.true:
// y = A[i][j] * 2
T1 = i * n2A
T1 = T1 + j
T2 = T1 * w
T3 = T_baseA[T2]
T4 = T3 * 2
y = T4
// z = B[k][m] + 1
T5 = k * n2B
T5 = T5 + m
T6 = T5 * w
T7 = T_baseB[T6]
T8 = T7 + 1
z = T8
goto F.next
// if false 分支
F.false:
// y = A[i][k] / 3
T9 = i * n2A
T9 = T9 + k
T10 = T9 * w
T11 = T_baseA[T10]
T12 = T11 / 3
y = T12
// z = B[k][n] - 1
T13 = k * n2B
T13 = T13 + n
T14 = T13 * w
T15 = T_baseB[T14]
T16 = T15 - 1
z = T16
goto F.next
// 循环尾部
F.next:
a = a - 1
goto LE
// 循环结束
E.false:
100 (j>, a, b, 104) // if a>b 成立,跳转到 E.true (104)
101 (j, _, _, 102) // 否则跳转到 L1 (102)
102 (j>, c, d, 104) // if c>d 成立,跳转到 E.true (104)
103 (j, _, _, 150) // 否则跳转到 E.false (150)
// E.true: 计算基地址
104 (-, A, C_A, T_baseA) // T_baseA = A - C_A
105 (-, B, C_B, T_baseB) // T_baseB = B - C_B
106 (j==, x, 0, 109) // if x==0 成立,跳转到 F.true (109)
107 (j, _, _, 120) // 否则跳转到 F.false (120)
// F.true: y = A[i][j] * 2
108 (*, i, n2A, T1) // T1 = i * n2A
109 (+, T1, j, T1) // T1 = T1 + j
110 (*, T1, w, T2) // T2 = T1 * w
111 (=[], T_baseA, T2, T3) // T3 = A[i][j]
112 (*, T3, 2, T4) // T4 = T3 * 2
113 (=, T4, _, y) // y = T4
// z = B[k][m] + 1
114 (*, k, n2B, T5) // T5 = k * n2B
115 (+, T5, m, T5) // T5 = T5 + m
116 (*, T5, w, T6) // T6 = T5 * w
117 (=[], T_baseB, T6, T7) // T7 = B[k][m]
118 (+, T7, 1, T8) // T8 = T7 + 1
119 (=, T8, _, z) // z = T8
120 (j, _, _, 136) // 跳转到 F.next (136)
// F.false: y = A[i][k] / 3
121 (*, i, n2A, T9) // T9 = i * n2A
122 (+, T9, k, T9) // T9 = T9 + k
123 (*, T9, w, T10) // T10 = T9 * w
124 (=[], T_baseA, T10, T11) // T11 = A[i][k]
125 (/, T11, 3, T12) // T12 = T11 / 3
126 (=, T12, _, y) // y = T12
// z = B[k][n] - 1
127 (*, k, n2B, T13) // T13 = k * n2B
128 (+, T13, n, T13) // T13 = T13 + n
129 (*, T13, w, T14) // T14 = T13 * w
130 (=[], T_baseB, T14, T15) // T15 = B[k][n]
131 (-, T15, 1, T16) // T16 = T15 - 1
132 (=, T16, _, z) // z = T16
// F.next: 循环尾部
133 (-, a, 1, a) // a = a - 1
134 (j, _, _, 100) // 跳回 LE (100)
// E.false: 循环结束
150
数组访问优化:
第 104-105 行:在循环体开始处计算数组基地址(避免重复计算)
两个分支共享相同的基地址寄存器
地址计算:
(行索引 * 列数 + 列索引) * 元素大小
100 (j>, a, b, 104) // if a>b 成立,跳转到 E.true (104)
101 (j, _, _, 102) // 否则跳转到 L1 (102)
102 (j>, c, d, 104) // if c>d 成立,跳转到 E.true (104)
103 (j, _, _, 150) // 否则跳转到 E.false (150)
// E.true: 计算数组基地址
104 (*, low1A, n2A, T_temp1) // T_temp1 = low1A * n2A
105 (+, T_temp1, low2A, T_temp1) // T_temp1 += low2A
106 (*, T_temp1, n3A, T_temp1) // 三维数组需*n3,二维可省略
107 (*, T_temp1, w, T_temp1) // T_temp1 *= w
108 (-, A, T_temp1, T_baseA) // T_baseA = A - T_temp1 (A的调整基址)
109 (*, low1B, n2B, T_temp2) // T_temp2 = low1B * n2B
110 (+, T_temp2, low2B, T_temp2) // T_temp2 += low2B
111 (*, T_temp2, w, T_temp2) // T_temp2 *= w
112 (-, B, T_temp2, T_baseB) // T_baseB = B - T_temp2 (B的调整基址)
113 (j==, x, 0, 116) // if x==0 成立,跳转到 F.true (116)
114 (j, _, _, 127) // 否则跳转到 F.false (127)
// F.true: y = A[i][j] * 2
115 (*, i, n2A, T1) // T1 = i * n2A
116 (+, T1, j, T1) // T1 = T1 + j
117 (*, T1, w, T2) // T2 = T1 * w (字节偏移)
118 (=[], T_baseA, T2, T3) // T3 = A[i][j]
119 (*, T3, 2, T4) // T4 = T3 * 2
120 (=, T4, _, y) // y = T4
// z = B[k][m] + 1
121 (*, k, n2B, T5) // T5 = k * n2B
122 (+, T5, m, T5) // T5 = T5 + m
123 (*, T5, w, T6) // T6 = T5 * w (字节偏移)
124 (=[], T_baseB, T6, T7) // T7 = B[k][m]
125 (+, T7, 1, T8) // T8 = T7 + 1
126 (=, T8, _, z) // z = T8
127 (j, _, _, 143) // 跳转到 F.next (143)
// F.false: y = A[i][k] / 3
128 (*, i, n2A, T9) // T9 = i * n2A
129 (+, T9, k, T9) // T9 = T9 + k
130 (*, T9, w, T10) // T10 = T9 * w (字节偏移)
131 (=[], T_baseA, T10, T11) // T11 = A[i][k]
132 (/, T11, 3, T12) // T12 = T11 / 3
133 (=, T12, _, y) // y = T12
// z = B[k][n] - 1
134 (*, k, n2B, T13) // T13 = k * n2B
135 (+, T13, n, T13) // T13 = T13 + n
136 (*, T13, w, T14) // T14 = T13 * w (字节偏移)
137 (=[], T_baseB, T14, T15) // T15 = B[k][n]
138 (-, T15, 1, T16) // T16 = T15 - 1
139 (=, T16, _, z) // z = T16
// F.next: 循环尾部
140 (-, a, 1, a) // a = a - 1
141 (j, _, _, 100) // 跳回 LE (100)
// E.false: 循环结束
150
基地址计算完整体现:
-
第 104-108 行:完整计算
T_baseA = A - ((low1A * n2A + low2A) * w)
-
第 109-112 行:完整计算
T_baseB = B - ((low1B * n2B + low2B) * w)
-
使用临时变量
T_temp1
和T_temp2
存储中间结果