assembly TASM 8086中的“近跳转或调用不同的CS”错误

gorkyyrv  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(605)

我一直在学习8086汇编使用TASM。我试图使一个jmp,但由于某种原因,它给我以下错误:
错误tarea.ASM(42)接近跳转或调用不同的CS
错误tarea.ASM(46)接近跳转或调用不同的CS
错误目标区域。ASM(50)接近跳转或调用不同CS
错误区域。ASM(52)符号已经是不同类型:萨尔
我使用了几个宏(不确定这是它们的名称,但这是我的老师对它们的称呼),例如 ImprimeM,但错误不在任何带有宏的行中。
所讨论的代码将是:

include macs.pbl

Pila Segment
Pila ends
Datos Segment
    var db 1
    var1 db 1
    igualesM DB "Los numeros son iguales$"
    MI1 db "Deme el primer numero$"
    MI2 db "Deme el segundo numero$"
    M1 db "El primero es mayor$"
    M2 db "El segundo es mayor$"
    salir db "Presione s para salir$"
Datos ends

Codigo Segment
Assume cs:Codigo , ds:Datos

Inicio:
xor ax,ax
mov ax,datos
mov ds,ax

vuelta:
ImprimeM MI1

RecibirN
mov ah,var;lo muevo para poder reutilizar la macro manteniendo el primer numero recibido

ImprimeM MI2
RecibirN

mov al,ah   ; lo regreso para poder hacer cmp

cmp al,var
jz iguales
jns mayor1
js mayor2

iguales:
    ImprimeM igualesM
    jmp short salir

mayor2:
    ImprimeM MI2
    jmp short salir

mayor1:
    ImprimeM MI1
    jmp short salir

salir:
    mov ah,4ch
    int 21h

Terminar
ends ;aqui termina el programa
    End inicio

任何帮助都是感激不尽的

xsuvu9jc

xsuvu9jc1#

TASM错误消息“Near jump or call to different CS”是关于编写了jmp short salir指令,其中jmp short指令是跳转,并且目标驻留在与包含指令本身的段不同的段中。跳转到不同段内将需要跳转,而且在目标地址上有可执行代码。在目标位于只包含数据的 Datos 段中的程序中,情况就不是这样了。
TASM错误消息“符号已经是不同类型:SALIR”是关于使用用户定义的符号 salir 作为 Datos 段和 Codigo 段中的标签。标签代表定义它的段中的偏移地址。您定义的标签必须是唯一的,因为同一标签不可能代表2个不同的偏移地址。
您可以通过多种方法解决此问题,但在message标签中添加一个合适的前缀可以解决此问题:

msgSalir db "Presione s para salir$"

您已经在 igualesigualesM 的比较中应用了这个技巧。
第一页第二页
上面的宏调用是错误的,因为此时在程序中您不想再次显示 * 输入消息 *。您想显示标记为 M1M2 的结果。
下面是一个优化版本:

  • 在执行mov ax, datos之前的xor ax, ax是多余的!只需删除它。
  • 在执行cmp al, var之前的mov al, ah是冗余的!您可以用单个cmp ah, var替换该对。
  • cmp al,varjz igualesjns mayor1js mayor2中,最后一个条件跳转可以被认为是多余的,因为SF=1的条件是不可避免的。只要对代码进行一些重构,就可以将其从程序中省略。由于您要比较有符号数,最好对JumpIfGreater使用适当的带符号条件跳转jg,在cmp之后,使用je(JumpIfEqual)比使用jz(JumpIfZero)更符合习惯。
Inicio:
  mov   ax, datos
  mov   ds, ax
vuelta:
  ImprimeM MI1
  RecibirN
  mov   ah, var               ; Copy 1st number to AH
  ImprimeM MI2
  RecibirN
  cmp   ah, var               ; Compare directly from AH
  mov   dx, OFFSET igualesM   ; iguales   num1 is equal to num2
  je    imprime
  mov   dx, OFFSET M1         ; mayor1    num1 is greater than num2
  jg    imprime
  mov   dx, OFFSET M2         ; mayor2    num1 is less than num2
print:
  ImprimeM dx
  mov   ax, 4C00h             ; DOS.TerminateWithReturncode
  int   21h
yduiuuwa

yduiuuwa2#

nvm,我把标签名称“salir”改为“sali”,这就解决了,为什么?我不知道
编辑:原来我是个白痴,我有一个名为salir的变量,我也试图将其用作标签

相关问题