I have been learning 8086 assembly using TASM. I am trying to make a jmp
but for some reason it gives me the following errors:
Error tarea.ASM(42) Near jump or call to different CS
Error tarea.ASM(46) Near jump or call to different CS
Error tarea.ASM(50) Near jump or call to different CS
Error tarea.ASM(52) Symbol already different kind: SALIR
I'm using several macros (not sure that's their name but that's what my teacher calls them) eg. ImprimeM, but the error isn't in any of the lines with macros.
The code in question would be:
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
Any help is appreciated
CodePudding user response:
The TASM error message "Near jump or call to different CS" is about having written a jmp short salir
instruction where the jmp short
instruction is a near jump and the target resides in a segment different from the one that contains the instruction itself. Jumping to within a different segment would require a far jump, but also to have executable code at the target address. This would not be the case in your program where the target is within the Datos segment that only contains data.
The TASM error message "Symbol already different kind: SALIR" is about having used the user-defined symbol salir as a label both in the Datos segment as well as in the Codigo segment. A label represents an offset address in the segment where it is defined. Labels that you define have to be unique since it is not possible for the same label to represent 2 different offset addresses.
You could solve it in a number of ways, but adding a suitable prefix to the message label can do the trick:
msgSalir db "Presione s para salir$"
You applied this trick already with iguales vs igualesM.
mayor2: ImprimeM MI2
mayor1: ImprimeM MI1
The above macro invokations are wrong in that at this point in your program you don't want to display the input messages again. You want to show the results that are labeled M1 and M2.
Here's an optimized version:
- The
xor ax, ax
before doingmov ax, datos
is redundant! Just remove it. - The
mov al, ah
before doingcmp al, var
is redundant! You can replace the pair by a singlecmp ah, var
. - In
cmp al,var
jz iguales
jns mayor1
js mayor2
, the last conditional jump can be considered redundant as the SF=1 condition is inevitably the case. With a little bit of restructuring the code, you can omit it from the program. And since you want to compare signed numbers, better use the appropriate signed conditional jumpsjg
for JumpIfGreater andjl
for JumpIfLess. Also, following acmp
it is more idiomatic to useje
(JumpIfEqual) thanjz
(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
CodePudding user response:
nvm, I changed the label name "salir" to "sali", that solved it, why? I have no idea
EDIT: turns out im an idiot and I had a variable named salir that i was also trying to use as a label