我的汇编代码如下:
.model small
.code
.stack 100h
public _putchar
;---------------------
;Putchar proc
;---------------------
_putchar proc
push bp
mov bp,sp
mov dl,[bp+4]
mov ah,2
int 21h
pop bp
ret
_putchar endp
end
然后,我从C调用此过程如下:
extern void putchar(char x);
int main(void)
{
putchar('x');
return 0;
}
要编译和链接,我使用以下命令行(按顺序)
tcc -c -ms pchar.c
tasm putchar.asm
tlink pchar putchar, pchar
到目前为止,我们从putchar.asm获取了.obj,并从链接这两个文件获得了.exe文件。
我还应该提到我们(在课堂上)使用turbo汇编程序版本2.01 (tasm)和turbo链接版本2.0 (tlink)和Turbo C版本2.01 (tcc)
问题出现在这里,当我运行.exe文件时,我得到输出'x'应该是, 但它被困在那里,它没有结束。
我要感谢任何帮助,提前谢谢。
答案 0 :(得分:1)
我想说,也许ret
错了,你可能需要一种不同类型的回报。
如果我正确的话,可能也会从堆栈中删除参数,pascal惯例。它会是这样的:
ret 4
注意:由于您是16位,因此可能是ret 2
而不是ret 4
。它取决于all
指令之前使用的推送指令。
否则,可以通过putchar
更改__cdecl
的声明。
extern __cdecl void putchar(char x);
请注意,在调试器中,您将看到堆栈是否在返回时被关注(即add sp, 4
到"输出"输入参数 - 因为您是16位,它可能是2而不是4。)
我仍然对您使用bp+4
而非bp+8
感到惊讶。你是16位,哇!
有关calling conventions的更多信息。
旁注:
您可能希望避免使用名为putchar()
的函数,因为它是在标准库中定义的,尽管在您的情况下您肯定不会受到该问题的影响。
答案 1 :(得分:1)
我观察到的两种可能性是调用例程可能正在使用AX
和DX
。
我非常怀疑这会有所帮助,但是在例行程序之前和之后尝试推动和弹出它们。
使用debug确认或反驳此信息。在调用例程之前放置一个断点,然后跳过它(而不是它)看看编译器的代码是否想要在调用ASM子例程之后使用AX
或DX
。
哦,我同意Alexis Wilke,改名。