【问题标题】:Retrieving values through address in assembly通过汇编中的地址检索值
【发布时间】:2023-03-24 04:52:01
【问题描述】:

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


这是我们的代码:

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

请帮忙。谢谢!

【问题讨论】:

  • re:edit: 现在你将 ebx 推入循环内(在你已经在循环外的 ebx 中销毁调用者的数据之后)。只有一个对 printf 的调用应该在循环内:使用 mov 而不是 push 的调用。您需要使用调试器并查看代码的作用。有很多东西是错误的,你会从自己发现它中学到更多。此外,您仍然没有对这里的数组做任何事情。不清楚您第一次尝试做什么,我的回答是基于您想打印 0、8、16 等的猜测。

标签: windows assembly nasm


【解决方案1】:

您是否正在尝试检索“地址的值”,就像您在文本中所说的那样? (即指针本身的数值)。您正在使用push prompt 执行此操作,以推送指向格式字符串的指针。

或者您想要地址的值?即取消引用指针/标签。您正在使用 push [i] 进行此操作。

当您从 [i+eax] 加载时,您正在从数据部分中的 i 之外加载垃圾,其中 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

请参阅 wiki 以获取 NASM 手册、英特尔 insn 参考手册以及许多其他内容的链接。

【讨论】:

  • 嗨,彼得先生,我们更新了这个问题来回答您的问题。请检查。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多