我们正在尝试检索第一个和第二个地址的值,但它正在返回垃圾。请帮忙。
这是我们的代码:
global _main
extern _printf, _system, _scanf, _gets, _getchar
section .text ; Code section
_main:
; clear screen
push clr
call _system
add esp, 4
;push dword [i]
;push prompt
;call _printf
;add esp, 8
;MOV EAX, 0001
;MOV dword [i+EAX], 0002
;push dword [i+EAX]
;push prompt
;call _printf
;add esp, 8
MOV EAX, 0001
MOV EBX, 0003
ARPLUS:
;FIRST
MOV dword [i+EAX], EBX
push dword [i+EAX]
push prompt
call _printf
add esp, 8
ADD EAX, 0008
INC EBX
;SECOND
MOV dword [i+EAX], EBX
push dword [i+EAX]
push prompt
call _printf
add esp, 8
ADD EAX, 0008
INC EBX
;THIRD
MOV dword [i+EAX], EBX
push dword [i+EAX]
push prompt
call _printf
add esp, 8
;INC EAX
;INC EBX
;RETRIEVE FIRST
ADD EAX, 0008
;MOV dword [i+EAX], EBX
push dword [i+EAX]
push prompt
call _printf
add esp, 8
;INC EAX
;INC EBX
;RETRIEVE SECOND
ADD EAX, 000F
;MOV dword [i+EAX], EBX
push dword [i+EAX]
push prompt
call _printf
add esp, 8
ret
section .data
clr db "cls",0
prompt db "The number you entered is %d",13,10,0
i dd 0
< ------------------------------------------->
更新2 感谢Peter Cordes的精彩建议!
要回答您的一些问题,以下是我们负责执行的代码的目标:
促进数组代码存储n个数字。意思是,我们需要使用内存空间和分配来存储数字和值。 作为示例,我们尝试将数字3,4,5存储到连续的内存堆/空间。 为了测试可靠性和数据真实性,我们尝试将3,4,5存储到我们应该是连续的内存堆中,并尝试通过重新访问内存空间并打印它们的值来“重新打印”或“重新访问”值。但我们没有成功。 因此,根据您的建议,我尝试重做它,但是:它没有产生相同的结果。它没有存储值3,4,5(或至少3),并重新打印这些值以证明它们存储在内存中。
我已经重新设计了你的代码建议,使其循环,但它只是无限循环。
global _main
extern _printf, _system,
section .text ; Code section
_main:
; clear screen
push clr
call _system
add esp, 4
MOV EAX, 0001
MOV EBX, 0003
MOV ECX, 0004 ; Counter for looping conditions
AGAIN:
push ebx
MOV EBX, [i] ; where does storing of 3, 4, 5 begin?
push ebx
push prompt
call _printf
add ebx, 8
mov [esp+4], ebx
mov dword [esp], prompt
call _printf
DEC ECX ; ECX is the counter to check loop conditions
CMP ECX, 0000 ; ECX is checked if it's still non negative
JGE AGAIN ; If it is, then "AGAIN" is re-performed
JMP LAST ; If not, then it will end the code.
LAST:
add esp, 8
pop ebx
ret
ret
section .data
clr db "cls",0
prompt db "Value is %d",13,10,0
i dd 0
对不起,我是汇编语言的新手。我的循环出了什么问题?它为什么无限期运行?我试图做的逻辑是:
计数器是ECX,它决定了循环条件(由ECX指示) 到达printf后,ECX会递减。 CMP检查ECX是否还是负数并返回“再次”。 但它无限循环。我希望你不介意,但请尽可能对我的代码(完整)进行可能的更正。对不起,我是汇编语言的新手。
请帮忙。谢谢!
答案 0 :(得分:0)
您是否正在尝试检索"地址的价值",就像您在文中所说的那样? (即指针本身的数值)。您正在使用push prompt
执行此操作,以将指针推送到格式字符串。
或者您希望值地址?即取消引用指针/标签。您使用push [i]
进行此操作。
从i
加载时,您从数据部分的[i+eax]
以外加载垃圾,其中eax非零。
如果你想打印i,那么i + 8,然后是i + 16,做类似的事情:
push ebx
mov ebx, [i] ; ebx is call-preserved, so we can keep a var live in a reg across calls
push ebx
push prompt
call _printf
; add esp, 0x8 ; instead of popping, reuse the space:
; at this point, eax = return value of printf, i.e. number of chars printed.
; adding to it and using it as an array index for i was your problem.
add ebx, 8
mov [esp+4], ebx
mov [esp], prompt ; called functions "own" their args, and may have clobbered, so re-do the store. But with mov instead of push, because the stack pointer is already offset
call _printf
; put this in a loop with a cmp ebx, something / jle instead of fully unrolling it.
add esp, 8 ; *now* pop the args, after all the calls.
pop ebx ; restore ebx, which we pushed at the start because *we're* not allowed to modify it. Our caller might break otherwise.
ret
有关NASM手册,英特尔insn参考手册以及其他许多内容的链接,请参阅x86 wiki。