通过汇编中的地址检索值

时间:2016-02-27 03:42:57

标签: windows assembly nasm

我们正在尝试检索第一个和第二个地址的值,但它正在返回垃圾。请帮忙。

这是我们的代码:

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是否还是负数并返回“再次”。 但它无限循环。我希望你不介意,但请尽可能对我的代码(完整)进行可能的更正。对不起,我是汇编语言的新手。

请帮忙。谢谢!

1 个答案:

答案 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参考手册以及其他许多内容的链接,请参阅 wiki。