我已经编写了以下汇编代码,用于添加10个数字。我能够编译并执行它但是我得到了错误的结果。 我只是想知道如何在scree上打印 total 的值。
section .data
num1: dw 10, 20, 30, 40, 50, 10, 20, 30, 40, 50
total: dw 0
msg : db "sum=%d",10,0
section .text
extern _printf
global _main
_main:
push ebp
mov ebp,esp
mov ebx,num1 ;point bx to first number
mov ecx,10 ;load count of numbers in ecx
mov eax,0 ;initialize sum to zero
loop:
add eax,[ebx]
add ebx,2
sub ecx,1
jnz loop
mov [total],eax
push total
push msg
call _printf
pop ebp
mov esp,ebp
ret
溶液
section .data
num1: dd 10, 20, 30, 40, 50, 10, 20, 30, 40, 50,300
total: dd 0
msg : dd "sum=%d",10,0
section .text
extern _printf
global _main
_main:
push ebp
mov ebp,esp
mov ebx,num1 ;point bx to first number
mov ecx,11 ;load count of numbers in ecx
mov eax,0 ;initialize sum to zero
loop:
add eax,[ebx]
add ebx,4
sub ecx,1
jnz loop
mov [total],eax
push dword [total]
push msg
call _printf
mov esp,ebp
pop ebp
ret
答案 0 :(得分:3)
您正在使用32位内存访问来处理16位值。
数组的每个元素都是16位宽。但是,由于eax
是32位宽,因此以下内容将数组视为每个元素也是32位宽:
add eax,[ebx]
以下也不完全正确,原因完全相同:
mov [total],eax
我认为还有一个问题是你在调用total
之前推送printf()
的地址,而你应该推送它的值
另外,正如@JasonD指出的那样,你需要在调用printf()
后清理堆栈。
最后,
mov esp,ebp
指令应该被删除,因为它只会破坏你的堆栈指针。
答案 1 :(得分:3)
我在这里看到了几个问题。首先,您已将num1
和total
声明为dw
。 dw
可能听起来像是“dword”,但它的意思是“数据字”。您希望这些是dd
- “数据dword”...因为这就是您使用它们的方式。 (并且add ebx, 4
不是2)如果你真的需要在32位代码中使用字(16位)值,那么它可以完成,但是很尴尬。
我看到的第二个问题是push total
在call _printf
推送total
的地址之前push dword [total]
。你想要内存的“[内容]”,所以push msg
。 (add esp, 8
是正确的)
在此之后,您可能需要add esp, 4 * 2
(我喜欢将其写为mov esp, ebp
- 两个参数,每个4个字节)。可以“推迟”此堆栈清理 - pop ebp
将解决您的问题,但需要在{{1}} !!!
......可能会有更多......
答案 2 :(得分:2)
dw 定义了16位实体,但add eax,[ebx]
正在添加32位实体。在 [ebx] 之前将 dw 更改为 dd 或将 WORD PTR 更改为 [ebx] 。此外,正如NPE指出的那样,您需要更改将 eax 存储到总计的处理方式。