Reputation: 3158
Why isn't my 'show_msg' function working properly?
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!$'
Upvotes: 1
Views: 898
Reputation: 821
The program would not work properly because DX does NOT point to the address of "str1".
First, you push the address of str1 into the stack, which SP points to. And that is no problem.
But after you call a function "show_str" to print str1, SP will no longer point to str1, because the value of original IP is pushed into the stack, on which the SP points, now.
You did not realize the change of SP and still tried to pass the value of SP to DX, which is supposed to store the address of the string to be printed.
My advice is that you should use "normal" style to write programs, because that will make our life easier unless you are exploring the secrets of the language itself.
This is my program.
;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!$"
Upvotes: 1
Reputation: 71070
Your code has a fundamental flaw in it.
Firstly, bp can also be used as a pointer.
You should index the stack using the bp register and not the bx register. The [bp] form uses the SS segment by default whereas the [bx] form uses DS as the default segment. This means that if DS != SS you will be not be reading the value pushed onto the stack if you use [bx] but some other undefined value.
So, the correct version is:-
show_msg:
mov bp,sp
mov ah,9
mov dx,[bp+2]
int 21h
ret
If your function needs some local storage, then the general form is:-
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
Upvotes: 2
Reputation: 19286
Most probably because [sp]
upon entry to the function contains the address of the return code, which - in case of this program - will be whatever address pop ax
at the beginning is under. Try changing mov dx, [bx]
to mov dx, [bx+2]
, which will cause the value of the argument pushed before the entry to the function to be retrieved.
Upvotes: 5