在MASM([assembly][x86])中尝试通过引用传递参数时获得错误的值

vbkedwbf  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(114)

我正在学习如何在MASM中通过引用传递和访问值。
我编写了一个简单的程序,使用Irvine.inc库显示val1val2

INCLUDE Irvine32.inc
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCall: DWORD

.data               ;date values
    array DWORD 100, 100, 200
    val1 DWORD 50
    val2 DWORD 6000
    charVal BYTE 'x', 0

.code               ;Code
main PROC
    
    mov eax, val1               ;this is a test to see if it works properly. 
    call WriteDec               ;writes eax in Decimal form to the console
    
    push OFFSET val1            ;push two values by reference onto the stack
    push OFFSET val2            
    call PrintNum

    INVOKE ExitProcess, 0
main ENDP

PrintNum PROC
    push ebp                    ;save ebp so we can go back to the program
    mov ebp, esp                ;esp should point to the top of the stack
    pushad                      ;why do we need to do this?
    mov eax, 0                  ;zero out eax because I though that might be the problem
    mov eax, [ebp+12]           ;this should move what is in the value of ebp+12 into eax (val1)
    call WriteDec               ;this writes what is in eax to the console
    mov eax, [ebp+8]            ;this should move what is in the value of ebp+8 into eax (val2)
    call WriteDec               ;this writes what is in eax to the console
    pop ebp                     ;get back to correct ebp section of the code
    popad                       ;needed to do this because pushad from before
    ret
PrintNum ENDP
End main

字符串
程序没有写出地址中的值。我做错了什么?
在考虑了@Jester所说的之后,我的代码可以使用添加的mov eax, [eax]
我现在试着在一个不同的测试程序中再做一次,它在没有mov eax, [eax]的情况下也能工作。这里有什么区别?

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCall: DWORD

.data               ;date values
    val1 DWORD 200
    val2 DWORD 100

.code               ;Code
main PROC
    push val1       ;needed to add the offset not the value
    push val2       ;needed to add the offset not the value
    call PrintVars

    INVOKE ExitProcess, 0
main ENDP

PrintVars PROC
    push ebp
    mov ebp, esp
    mov eax, [ebp+12]   ;mov address of val1 into eax
    ;mov eax, [eax]     ;use address to get actual value
    call WriteDec       ;write the dec to the console
    call Crlf           ;carage return
    mov eax, [ebp+8]    ;mov address of val2 into eax
    ;mov eax, [eax]     ;deference address to actual value
    call WriteDec       ;write the dec to console
    call Crlf           ;carage return
    pop ebp
    ret
PrintVars ENDP
End main

0qx6xfy6

0qx6xfy61#

因为您使用的是MASM,所以像push OFFSET val1这样的指令会推送标签 val1 的地址,而像push val1这样的指令会推送存储在地址 val1 的值。

  • NASM中,像push val1这样的指令将推送标签 val1 的地址,而像push dword [val1]这样的指令将推送存储在地址 val1 的值。*

方案一

在第一个程序中,你推标签的地址,你的 * PrintList * proc将不得不解引用,因为你想要存储在地址的值,这样你就可以打印它。

push OFFSET val1    ; Push two values by reference onto the stack
  push OFFSET val2            
  call PrintNum

  ...

PrintNum PROC
  mov  eax, [esp+8]   ; OFFSET val1
  mov  eax, [eax]     ; Get value stored at val1
  call WriteDec
  mov  eax, [esp+4]   ; OFFSET val2
  mov  eax, [eax]     ; Get value stored at val2
  call WriteDec
  ret

字符串

方案二

在第二个程序中,您推送了存储在标签地址处的值,您的 PrintVars proc不再需要解引用,因为您已经拥有了值本身。

push val1           ; Push two values by value onto the stack
  push val2            
  call PrintVars

  ...

PrintVars PROC
  mov  eax, [esp+8]   ; Value stored at val1
  call WriteDec
  mov  eax, [esp+4]   ; Value stored at val2
  call WriteDec
  ret

rnmwe5a2

rnmwe5a22#

这个错误是在我的mov eax, [ebx+12]中。在一行中的deference是不够的。另一个deference必须accure. mov eax, [eax]。完整的代码如下。

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCall: DWORD

.data               ;date values
    val1 DWORD 200
    val2 DWORD 100

.code               ;Code
main PROC
    push OFFSET val1       ;needed to add the offset not the value
    push OFFSET val2       ;needed to add the offset not the value
    call PrintVars

    INVOKE ExitProcess, 0
main ENDP

PrintVars PROC
    push ebp
    mov ebp, esp
    mov eax, [ebp+12]   ;mov address of val1 into eax
    mov eax, [eax]     ;use address to get actual value
    call WriteDec       ;write the dec to the console
    call Crlf           ;carage return
    mov eax, [ebp+8]    ;mov address of val2 into eax
    mov eax, [eax]     ;deference address to actual value
    call WriteDec       ;write the dec to console
    call Crlf           ;carage return
    pop ebp
    ret
PrintVars ENDP
End main

字符串

相关问题