im having a small issue with my assembly function that i made.
; Im failing super hard at writing this
; Function.
.MODEL c, small
.DATA?
.DATA
curpos_ PROTO C columns_:BYTE, rows_:BYTE
.CODE
public curpos_
curpos_ PROC C columns_:BYTE, rows_:BYTE
mov dh, columns_
mov dl, rows_
mov bh, 0
mov ah, 2
int 10h
ret
curpos_ ENDP
END
And my C file in which i prototype the assembly function.
#include<stdio.h>
#include<conio.h>
#include<math.h>
void clrscr(void);
extern char _columns, _rows;
extern void _curpos(char _columns, char _rows);
void arcradius() {
float w;
float h;
float radi = w / 2.0;
float value;
clrscr();
...
_curpos(20,40);
getch();
arcradius();
}
The issue im having is that my C program is not giving the assembly function the right arguments, in my C file i use _curpos(20,40) but it doesn't use the values in the parentheses. Instead it uses some garbage number from the previous scanf(); input.
Is there something im mis-declaring, prototyping incorrectly, or forgot?
I'm using OpenWatcom and MASM 6.11.
Thanks, Noah "MadDog" Buzelli
EDIT: Here is the fixed assembly function
; Im failing super hard at writing this
; Function.
.MODEL small
.DATA?
.DATA
curpos PROTO C _columns:BYTE, _rows:BYTE
.CODE
public curpos
curpos PROC C _columns:BYTE, _rows:BYTE
push bx
mov dh, BYTE PTR _columns
mov dl, BYTE PTR _rows
mov bh, 0
mov ah, 2
int 10h
pop bx
ret 4
curpos ENDP
END
And here is my C prototype
extern void __stdcall curpos(char columns, char rows);
Thank you Mgetz :)
CodePudding user response:
So you need to specify the Calling convention for the assembly method. By default open watcom uses __stdcall
So it should look something like this:
extern void __stdcall curpos(char _columns, char _rows);
This asm is probably right, but untested. We're doing everything manually, not relying on MASM's magic to set up BP and calculate the position of args on the stack.
_columns$ = 4 ; size = 1
_rows$ = 6 ; offsets relative to the frame pointer
; saved-BP at [bp 0], ret addr at [bp 2], first arg at [bp 4]
_curpos@4 PROC ; COMDAT
push bp
mov bp, sp ; for access to args on the stack, [sp] isn't valid
push bx ; save/restore the caller's BX
mov dh, BYTE PTR _columns$[bp]
mov dl, BYTE PTR _rows$[bp]
mov bh, 0 ; page=0
mov ah, 2
int 10h ; int 10h / AH=2 - BIOS Set cursor position
pop bx
pop bp ; no mov sp,bp needed, SP is already good
ret 4 ; pop ret addr, then SP =4
_curpos@4 ENDP
For what it's worth it may be better to use inline assembly for this instead of doing a full implementation in asm. If you use inline asm the compiler takes care of all of this, you just have to get the inputs into registers, not write code that returns.