1

为什么我的“show_msg”功能不能正常工作?

org 100h

push str1
call show_msg
pop ax

mov ah, 4Ch
int 21h

show_msg:
mov ah, 9
mov bx, sp ;in 16bit bx is the only register that can act as a pointer (besides di and si)
mov dx, [bx]
int 21h
ret


str1 db 'Hello world!$'
4

3 回答 3

5

很可能是因为[sp]在进入函数时包含返回代码的地址,在这个程序的情况下,它将是pop ax开头的任何地址。尝试更改mov dx, [bx]mov dx, [bx+2],这将导致在函数条目之前推送的参数的值被检索。

于 2012-05-01T09:08:47.893 回答
2

您的代码存在根本缺陷。

首先,bp 也可以用作指针。

您应该使用 bp 寄存器而不是 bx 寄存器来索引堆栈。[bp] 形式默认使用 SS 段,而 [bx] 形式使用 DS 作为默认段。这意味着如果 DS != SS 如果您使用 [bx] ,您将不会读取压入堆栈的值,而是使用其他一些未定义的值。

所以,正确的版本是:-

show_msg:
  mov bp,sp
  mov ah,9
  mov dx,[bp+2]
  int 21h
  ret

如果您的函数需要一些本地存储,那么一般形式是:-

function:
  mov bp,sp
  sub sp,amount of space for local storage

  some code, parameters are [bp+offset], local data are [bp-offset]

  mov sp,bp
  ret
于 2012-05-04T10:47:23.193 回答
1

该程序将无法正常运行,因为 DX 没有指向“str1”的地址。

首先,将 str1 的地址压入 SP 指向的堆栈。这没问题。

但是当你调用一个函数“show_str”来打印str1之后,SP将不再指向str1,因为原来IP的值被压入了SP指向的堆栈,现在。

你没有意识到 SP 的变化,仍然试图将 SP 的值传递给 DX,DX 应该存储要打印的字符串的地址。

我的建议是你应该使用“正常”的风格来编写程序,因为除非你在探索语言本身的秘密,否则这会让我们的生活更轻松。

这是我的程序。

    ;file: showmsg.asm (.COM)
    ;nasm -fbin showmsg.asm -o showmsg.com 

    org 0x100
    mov ax, cs
    mov ds, ax

    mov ax, str1     ;Transmit parameter to show_msg through AX
    call show_msg

mov ax, 4c00h
int 21h

show_msg:            ;the address offset of the string is stored in ax
    mov dx, ax       ;DS:DX=string address
    mov ax, 0900h    ;AH=09 
    int 21h
    ret
str1: db "Hello, world!$"
于 2014-03-15T16:19:27.587 回答