Проблемы со сборкой TASM

1) Итак, у меня есть этот код asm в файле .asm, в основном он делает что-то вроде

BEGIN


X:=2;  
Y:=2+X;
Z:=Y;

IF( Z > X ) THEN  
WRITELN("VALOR DE Z"); 
WRITELN( Z ); 
ELSE 
WRITELN("VALOR DE X"); 
WRITELN( X ); 
END; 

END programa1.

АСМ здесь:

   ;/StartHeader
INCLUDE macrose.mac
DOSSEG
.MODEL SMALL
STACK 100h
.DATA
            BUFFER      DB 8 DUP('$')  ;23h
            BUFFERTEMP  DB 8 DUP('$')  ;23h
            BLANCO  DB '#'
            BLANCOS DB '$'
            MENOS   DB '-$'
            COUNT   DW 0
            NEGATIVO    DB 0
            ARREGLO DW 0
            ARREGLO1    DW 0
            ARREGLO2    DW 0
            LISTAPAR    LABEL BYTE
            LONGMAX DB 254
            TOTCAR  DB ?
            INTRODUCIDOS    DB 254 DUP ('$')
                        MULT10  DW 1
                        NUM DW ?
                        X  dw ?
                        Y  dw ?
                        Z  dw ?
            T1 dw ?
            T2 dw ?
                        cadena1 db "VALOR DE Z",'$'
                        cadena2 db "VALOR DE X",'$'
.CODE
.386
BEGIN:
            MOV     AX, @DATA
            MOV     DS, AX
CALL  COMPI
            MOV AX, 4C00H
            INT 21H
COMPI  PROC
    I_ASIGNAR           2, X
    SUMAR               X, 2, T1
    I_ASIGNAR           T1, Y
    I_ASIGNAR           Y, Z
    I_MAYOR MACRO       X, Z, T2
        JF                  T2, P1
    WRITE               cadena1
    ADD                 Z, 30H
    WRITE               Z
        JMP                 Q1
P1: 
    WRITE               cadena2
    ADD                 X, 30H
    WRITE               X
Q1: 
        ret
COMPI  ENDP
END BEGIN

И когда я пытаюсь запустить его в cmd dosbox (cmd в win 7 не будет работать) с tasm file.asm, у меня возникают эти ошибки

Предупреждение codigo.asm() Открыть процедуру: COMPI

Неустранимая codigo.asm(55) Обнаружен неожиданный конец файла

Я не знаю, почему, потому что я почти уверен, что закрываю процедуру и начинаю, кроме того, последняя строка в моем файле - 54, и я не знаю, почему мне говорят, что проблема в строке 55.

Эти макросы я использую:

JF  MACRO VALOR1,DESTINO
    MOV AX,VALOR1
    CMP AX,1                   
    JNE  DESTINO

    ENDM

WRITE   MACRO MESSAGE
        PUSH AX ;EXTRA
        MOV AH, 09H
        LEA DX, MESSAGE
        INT 21H
        POP AX  ;EXTRA
    ENDM

I_ASIGNAR MACRO OPERANDO2, OPERANDO1
        PUSH AX
        MOV AX, OPERANDO2
        MOV OPERANDO1, AX
        POP AX
    ENDM

SUMAR   MACRO OPERANDO2, OPERANDO1, RESULTADO
        PUSH AX
                MOV AX, OPERANDO1
        ADD AX, OPERANDO2
        MOV RESULTADO, AX
        POP AX
    ENDM

I_MAYOR MACRO OPERANDO2, OPERANDO1, RESULTADO
    LOCAL LABEL1
    LOCAL SALIR
        PUSH AX
        MOV AX, OPERANDO1
        CMP AX, OPERANDO2
        JLE LABEL1
        MOV RESULTADO, 1
        JMP SALIR
    LABEL1:
        MOV RESULTADO, 0
    SALIR:
        POP AX
    ENDM

2) У меня также есть этот код на ассемблере, в основном он просто делает что-то вроде:

BEGIN


X:=2;  
Y:=2+X;
Z:=Y;

WRITELN("VALOR DE Z"); 
WRITELN( Z ); 


END programa1.

Асм здесь:

;/StartHeader
INCLUDE macrose.mac
DOSSEG
.MODEL SMALL
STACK 100h
.DATA
            BUFFER      DB 8 DUP('$')  ;23h
            BUFFERTEMP  DB 8 DUP('$')  ;23h
            BLANCO  DB '#'
            BLANCOS DB '$'
            MENOS   DB '-$'
            COUNT   DW 0
            NEGATIVO    DB 0
            ARREGLO DW 0
            ARREGLO1    DW 0
            ARREGLO2    DW 0
            LISTAPAR    LABEL BYTE
            LONGMAX DB 254
            TOTCAR  DB ?
            INTRODUCIDOS    DB 254 DUP ('$')
                        MULT10  DW 1
                        NUM DW ?
                        X  dw ?
                        Y  dw ?
                        Z  dw ?
            T1 dw ?
                        cadena1 db "VALOR DE Z",'$'
.CODE
.386
BEGIN:
            MOV     AX, @DATA
            MOV     DS, AX
CALL  COMPI
            MOV AX, 4C00H
            INT 21H
COMPI  PROC
    I_ASIGNAR           2, X
    SUMAR               X, 2, T1
    I_ASIGNAR           T1, Y
    I_ASIGNAR           Y, Z
    WRITE               cadena1
    ADD                 Z, 30H
    WRITE               Z
        ret
COMPI  ENDP
END BEGIN

Но у меня есть другая проблема (у меня нет ошибки открытой процедуры, почему?), что я печатаю: VALOR DE Z1 VALOR DE Z

-Почему я печатаю "VALOR DE Z" дважды? -1 это ответ, хотя он должен печатать только VALOR DE Z и 1, а не дважды. -Я использую те же макросы, что и выложил, а также работаю в Dosbox 0.74.

Есть идеи? Спасибо кстати.

П.Д. Im в Dell Inspiron 64bit n5150 Intel Core i7 2670Qm 2.20Ghz 6gb ram Почему формат кода не работает на issue2?


person ramro93    schedule 14.12.2015    source источник
comment
Я пытался исправить форматирование кода в этом последнем блобе кода, но, похоже, я не могу заставить его придерживаться.   -  person David Hoelzer    schedule 15.12.2015
comment
Я предлагаю удалить вопрос 2, оставив только вопрос 1. Затем задайте отдельный вопрос SO для вопроса 2.   -  person Michael Petch    schedule 15.12.2015
comment
Я думаю, что проблема с вашим вопросом № 1 заключается в том, что у вас есть эта строка I_MAYOR MACRO X, Z, T2 в процедуре COMPI. Слово MACRO там быть не должно. Я думаю, вы имели в виду I_MAYOR X, Z, T2. Я думаю, что это приводит TASM в замешательство, так как он думает, что вы запускаете новый макрос.   -  person Michael Petch    schedule 15.12.2015
comment
Вот так! Большое спасибо! Затем я задам новый вопрос для выпуска 2. Спасибо.   -  person ramro93    schedule 15.12.2015
comment
Я предполагаю, что это, вероятно, была ошибка копирования и вставки (типографская), когда вы кодировали. Если это так, я проголосую за закрытие вопроса №1, потому что на самом деле это была просто опечатка.   -  person Michael Petch    schedule 15.12.2015
comment
Что касается вопроса № 2, вы не можете использовать in 21h/ah=09h для прямого вывода целочисленных значений. Вы должны преобразовать целое число в строку, а затем вызвать int 21h/ah=09h в строковом буфере с преобразованным значением. Он распечатал данные, начиная с позиции переменной Z. Забавные символы, которые вы, вероятно, отображали на консоли, были значениями Ascii для слова в Z, затем он печатал T1 (при поиске $). Затем он продолжал, пока не нашел завершение $, который оказался в конце строки cadena1 Как только он нашел $, он остановился. Таким образом, cadena1 будет напечатано дважды.   -  person Michael Petch    schedule 15.12.2015
comment
Большое спасибо! последний вопрос, как я могу преобразовать целое число в строку с помощью строкового буфера? Цените помощь.   -  person ramro93    schedule 15.12.2015
comment
Обычный алгоритм состоит в том, чтобы взять целочисленное значение и разделить его на 10. Остаток можно добавить к ASCII '0', чтобы преобразовать цифру в печатный символ и сохранить его в строковом буфере. Вы продолжаете делить на 10 до тех пор, пока делимое не станет равным 0. Вы должны позаботиться о том, чтобы поменять местами цифры, поскольку они будут обрабатываться в обратном порядке. Вы можете найти примеры этого в Интернете, если вы посмотрите.   -  person Michael Petch    schedule 15.12.2015
comment
Понятно! Большое спасибо!   -  person ramro93    schedule 15.12.2015


Ответы (1)


Я совершенно уверен, что для MASM требуется COMPI ENDP, а для TASM требуется только ENDP. Кроме того, в одном из ваших утверждений есть слово MACRO:

COMPI  PROC
    I_ASIGNAR           2, X
    SUMAR               X, 2, T1
    I_ASIGNAR           T1, Y
    I_ASIGNAR           Y, Z
    I_MAYOR MACRO       X, Z, T2   ; <<<---  Remove "MACRO"
        JF                  T2, P1
    WRITE               cadena1
    ADD                 Z, 30H
    WRITE               Z
        JMP                 Q1
P1: 
    WRITE               cadena2
    ADD                 X, 30H
    WRITE               X
Q1: 
        ret
COMPI ENDP               

Это должно решить вашу проблему в вопросе № 1.

person David Hoelzer    schedule 15.12.2015