写在前面

在汇编语言中,针对数组操作,可以使用间接寻址,或者变址寻址。在变址寻址操作时,遇到了一系列问题,遂做总结,避免再犯。

问题描述

有一个带有8个WORD型数据的数组,想要对其偶数项进行求和

间接寻址方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
; Operators (Operator.asm)

; Demonstrates the TYPE, LENGTHOF, and SIZEOF operators

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,stdcall:dword

.data
arrofw WORD 1,2,1,2,1,2,1,2 ;数据中,偶数序求和结果为2*4,奇数序求和为1*4
sum WORD 0

.code
main PROC
mov EDI,OFFSET arrofw
add EDI,2 ;现在指向第二个数据
mov ECX,LENGTHOF arrofw
mov AX,0
L1:
add AX,[EDI] ;依次累加
add EDI,2*TYPE arrofw ;求偶数序,所以向后偏移
LOOP L1
mov sum,AX

invoke ExitProcess,0
main ENDP
END main

带比例因子的变址寻址方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
; Operators (Operator.asm)

; Demonstrates the TYPE, LENGTHOF, and SIZEOF operators

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,stdcall:dword

.data
arrofw WORD 1,2,1,2,1,2,1,2 ;数据中,偶数序求和结果为2*4,奇数序求和为1*4
sum WORD 0

.code
main PROC
mov AX,0
mov ESI,1
mov ECX,LENGTHOF arrofw
L1:
add AX,arrofw[ESI*TYPE arrofw] ;依次累加
add ESI,2 ;求偶数序,所以每次加2
LOOP L1
mov sum,AX

invoke ExitProcess,0
main ENDP
END main

犯的错误

  • 在使用寄存器时,没有考虑数据类型为WORD型,应该使用16位寄存器AX,而不是32位的EAX等等寄存器;
  • 为什么又使用了EDI,ESI等寄存器?因为在OFFSET指令中,返回的地址一般为32位的,所以用32位的EDI寄存器来存;ESI同理。 这里不能用DI或者SI