我想計算陣列中 1 的數量(使用 MASM32)。在第一次迭代中,我在EAX. 我得到的不是 00000000,而是 00010000。因此在 counter 中也得到了不正確的值ECX。
.386
.model small
.data
var1 dw 0,1,1
.code
main PROC
LEA ESI, var1
MOV EBX, 3
MOV ECX, 0
L1:CMP EBX, 0
JE L3
MOV EAX, [ESI]
CMP EAX, 0
JE L2
INC ECX
L2:DEC EBX
ADD ESI, 2
JMP L1
L3:INVOKE ExitProcess, 0
main ENDP
END main
看到這張圖片,得到 00010000EAX而不是 00000000 因為內容[ESI] 在開始時是 0

uj5u.com熱心網友回復:
您定義var1為word (16-bit) 而不是dword,但您正在加載dword (32-bit) 因為您加載的eax是一個 32 位大小的暫存器,因此您將獲得記憶體中的下一個字(即1) 在你的 dword 的上半部分。看這個例子:
x dw 1
y dw 2
z dw 3
# resulting memory layout:
# 01 00 02 00 03 00
# \_x_/ \_y_/ \_z_/
mov ax, [x] # you get 0001
mov eax, [x] # you get 00020001 !! because you are reading x AND y
movzx eax, word ptr [x] # you get 00000001
# 01 00 02 00 03 00
# \_x_/ \_y_/ \_z_/
# \ax_/
# \___eax___/
mov ax, [y] # you get 0002
mov eax, [y] # you get 00030002 !! because you are reading y AND z
movzx eax, word ptr [y] # you get 00000002
# 01 00 02 00 03 00
# \_x_/ \_y_/ \_z_/
# \ax_/
# \___eax___/
在您的情況下,它不是另一個命名變數,而是第二部分var1(您var1 dw 0,1,1定義了三個具有值 0000、0001、0001 的單詞 - 但與上面的示例相同,這里適用)。
var1 dw 0,1,1
# 00 00 01 00 01 00
# \___/ \___/ \___/
# \var1 \ \var1 4
# \var1 2
# \ax_/
# \___eax___/
因此,要么使用dd而不是使您的變數成為雙字dw(然后也增加esi4 而不是 2),或者通過將其存盤到較小的暫存器中來讀取一個字,例如ax或使用movzx(或movsx如果您需要一個帶符號的值) with word ptr,其中擴展值以填充整個暫存器。
var1 dd 0,1,1
# 00 00 00 00 01 00 00 00 01 00 00 00
# \__var1___/ \_var1 4__/ \_var1 8__/
# \___eax___/
請注意,如果您決定使用ax,那么請記住,向其中加載資料不會修改 的上半部分eax,而是會保留其先前的值,因此您無法寫入ax然后從中讀取eax,因為您將再次在上半部分。然后你需要做cmp ax, 0而不是cmp eax, 0太。您需要始終了解您正在閱讀或寫作的內容(以及數量)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/315398.html
