Assembly 多模块汇编程序

Assembly 多模块汇编程序,assembly,dos,tasm,multi-module,Assembly,Dos,Tasm,Multi Module,我在DOS中创建简单的多模块程序时遇到问题 我想要的是创建一个过程,用5递增ax,并从主过程调用它。但每次开始调试时,我都会遇到一个奇怪的问题,即无限长的一个指令周期: add [bx:si], al 下面是我的第一个文件: ;(tmp1.bat) .model small .386 extrn mytmp .code org 100h start: mov ax, 5 push ax call mytmp pop ax mov dl, al mov ah, 06h

我在DOS中创建简单的多模块程序时遇到问题

我想要的是创建一个过程,用5递增ax,并从主过程调用它。但每次开始调试时,我都会遇到一个奇怪的问题,即无限长的一个指令周期:

add [bx:si], al
下面是我的第一个文件:

;(tmp1.bat)
.model small
.386
extrn mytmp

.code
org 100h
start:
  mov ax, 5
  push ax
  call mytmp
  pop ax
  mov dl, al
  mov ah, 06h
  int 21h
  ret
end start
end
第二个文件:

;(tmp2.bat)
.model small
.386
public mytmp

.code
mytmp: 
  pop ax
  add ax, 5
  push ax
  ret
END
我做错了什么? 从DOS编译的注意事项:

tasm tmp1.bat
tasm tmp2.bat
tlink /t tmp1.obj tmp2.obj
此代码:

pop ax
add ax, 5
push ax
ret
这完全是无稽之谈,会导致撞车。您将从堆栈中弹出返回地址,向其中添加5,将其放回堆栈中,然后返回。因此,函数返回原始的预期返回地址加上5,这是一个任意位置,位于调用应该返回的位置后5个字节

显然,这是在某个指令的中间,所以反汇编程序会变得混乱,它向你显示你即将执行<代码> Ad[bx:si],A/<代码>这是一个毫无意义的、不存在的指令。 因此,无论您在
mytmp:
函数中使用这3条指令试图实现什么,它都是错误的,您不应该这样做。

此代码:

pop ax
add ax, 5
push ax
ret
这完全是无稽之谈,会导致撞车。您将从堆栈中弹出返回地址,向其中添加5,将其放回堆栈中,然后返回。因此,函数返回原始的预期返回地址加上5,这是一个任意位置,位于调用应该返回的位置后5个字节

显然,这是在某个指令的中间,所以反汇编程序会变得混乱,它向你显示你即将执行<代码> Ad[bx:si],A/<代码>这是一个毫无意义的、不存在的指令。
因此,无论您在
mytmp:
函数中使用这3条指令试图实现什么,它都是错误的,您不应该这样做。

TASM根据
mytmp
中的值将
call mytmp
作为间接调用进行汇编。它不知道
mytmp
是一个过程

改变

extrn mytmp


TASM根据
mytmp
中的值将
call mytmp
组装为间接调用。它不知道
mytmp
是一个过程

改变

extrn mytmp


你需要对“无限一个指令周期”做一些解释:它是什么(你认为),你如何知道它是一个无限周期,它在地球上的什么地方(我在代码中没有看到它)等等。顺便说一下,我们也很想知道你对那些“(tmp1.bat)”和“(tmp2.bat)”注释的意思和“(tmp2.bat)”是这些文件名。也就是说,我认为我的代码执行起来并不完全正确,正如我所希望的那样。所以我要你告诉我我的错误…当然。因此,这与代码的正确性(或缺乏正确性)无关,它更像是一种约定类型的东西,但如果做得不对,您可能会遇到麻烦:程序集文件具有
.asm
扩展名。扩展名
.bat
用于批处理文件,这些文件与程序集文件完全无关。关于您的代码不正确,您仍然没有对我第一条评论的要点做任何修改。以下是我在链接后从.com的debug获得的一些代码:…>mov ax,0005>推送ax>调用[010E]>添加[bx+si],al>。。。我假设我的代码链接不正确。好吧,在你的代码中,它说的是
mov ax
(这是毫无意义的,应该被
tasm
拒绝),但你的调试器说的是
mov ax,0005
。那么,它是哪一个呢?你需要对“无限一指令周期”做一些解释:它是什么(你认为),你如何知道它是一个无限周期,它在地球上的什么地方(我在代码中没有看到它)等等。顺便说一下,我们也很想知道你对这些(tmp1.bat)和(tmp2.bat)的意思注释.>“(tmp1.bat)”和“(tmp2.bat)”是这些文件名。也就是说,我认为我的代码执行起来并不完全正确,正如我所希望的那样。所以我要你告诉我我的错误…当然。因此,这与代码的正确性(或缺乏正确性)无关,它更像是一种约定类型的东西,但如果做得不对,您可能会遇到麻烦:程序集文件具有
.asm
扩展名。扩展名
.bat
用于批处理文件,这些文件与程序集文件完全无关。关于您的代码不正确,您仍然没有对我第一条评论的要点做任何修改。以下是我在链接后从.com的debug获得的一些代码:…>mov ax,0005>推送ax>调用[010E]>添加[bx+si],al>。。。我假设我的代码链接不正确。好吧,在你的代码中,它说的是
mov ax
(这是毫无意义的,应该被
tasm
拒绝),但你的调试器说的是
mov ax,0005
。那么,是哪一个呢?好吧,这不是问题,因为返回地址目前不在堆栈的顶部。尽管如此,我删除了所有使用堆栈的行,它仍然以相同的方式执行:(尽管,感谢您的研究:)不,这正是问题所在,因为在进入函数时,返回地址始终位于堆栈的顶部。好的。谢谢你的评论。但问题仍然存在。好吧,这不是问题,因为目前返回地址不在堆栈的顶部。尽管如此,我删除了所有使用堆栈的行,它仍然以相同的方式执行:(尽管,感谢您的研究:)不,这正是问题所在,因为在进入函数时,返回地址始终位于堆栈的顶部。好的。谢谢你的评论。但问题仍然存在。是的,在一次一位地从OP中费力地提取出所有必要的信息之后,事实证明这可能就是问题所在。是的,