Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
dastym4b
1 / 1 / 0
Регистрация: 22.02.2009
Сообщений: 18
1

Relative jump out of range

01.06.2009, 21:27. Просмотров 2809. Ответов 5
Метки нет (Все метки)

relative jump out of range 0008h bytes
говорит мне ошибку на строке где по сути вызываю макрос. причем до этого вызываю его два раза и никаких проблем... в чем беда?
кусок кода приблизительно такой, макрос запихнут в отдельном файле...
на одном из outch ошибка вылазит
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
stout:
        outch '|'
        movstr stabl[bx].fam,temfam,10
        outstr temfam
        outch '|'
        movstr stabl[bx].count,tempcou,3
        outstr tempcou
        outch '|'
        mov al,stabl[bx].sc1
        outword ax,3
        outch '|'
        mov al,stabl[bx].sc2
        outword ax,3
        outch '|'
        newline
        add bx,lens
    loop stout
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.06.2009, 21:27
Ответы с готовыми решениями:

Relative jump out of range by ... bytes
Есть задача на определенную клавишу совершать некое действие. При компиляции...

Relative jump out of range by __ bytes
Relative jump out of range by __ bytes (Адрес назначения условного перехода...

Ошибка "Relative jump out of range by 002Bh bytes"
Нужно отсортировать элементы матрицы по возрастанию, которые принадлежат ...

Jump out of range. Нужна консультация.
Доброго времени суток! Программа считывает из файла строку, обрабатывает и...

Near jump or call to different CS
Ни давно начал asm изучать и столкнулся с ошибками, ни могу организовать...

5
alex_x_x
бжни
2455 / 1662 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
01.06.2009, 21:37 2
не уверен что тут делает макрос но судя по ошибке похоже что ты слишком далеко пытаешься перепрыгнуть, одного байта не хватает для указания смещения, попробуй вначале указать директиву .386
0
dastym4b
1 / 1 / 0
Регистрация: 22.02.2009
Сообщений: 18
01.06.2009, 21:45  [ТС] 3
где указать и как не подскажете?
0
alex_x_x
бжни
2455 / 1662 / 134
Регистрация: 14.05.2009
Сообщений: 7,162
01.06.2009, 21:55 4
в самом верху до указания блоков кода итп
Assembler
1
.386
0
Haster
инженер-системотехник
111 / 110 / 5
Регистрация: 10.03.2009
Сообщений: 533
01.06.2009, 21:55 5
Приведи весь код, по этому куску не понять, но суть проблемы alex_x_x указал верно
0
dastym4b
1 / 1 / 0
Регистрация: 22.02.2009
Сообщений: 18
01.06.2009, 22:26  [ТС] 6
главный модуль
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
include io.asm
.MODEL  small
;==================================================================
;Описание структур
;==================================================================
tabl1 struc
    fam db 10 dup (' ')
    count db 3 dup (' ')
    sc1 db ?
    sc2 db ?
tabl1 ends
;==================================================================
tabl2 struc
    fam2 db 10 dup(' ')
    count2 db 3 dup (' ')
    sum db ?
tabl2 ends
;==================================================================
;Пересылка цепочек
;==================================================================
movstr macro src,dest,len
 
    push cx
    push si
    push di
    mov cx,len
    
    lea di,dest
    lea si,src
    
    rep movsb
    pop di
    pop si
    pop cx
    
endm
;==================================================================
;Сравнение цепочек
;==================================================================
cmpstr macro src,dest,len
    push cx
    push si
    push di
    mov cx,len
    lea di,dest
    lea si,src
    rep cmpsb
    
    pop di
    pop si
    pop cx
 
endm
;===================================================================
 
 
 
.stack  100h
 
.data
lens equ type tabl1
lenr equ type tabl2
;==================================================================
;Инициализация элементов исходной таблицы
;==================================================================
stabl tabl1 <'sidorov','rus',10,7>
    tabl1 <'ivanov','swe',8,7>
    tabl1 <'petrov','nor',1,4>
    tabl1 <'zuzukin','rus',7,8>
    tabl1 <'ushenko','ukr',3,4>
    tabl1 <'voronina','rus',9,7>
    tabl1 <'kabaeva','rus',6,7>
;==================================================================
n equ ($-stabl)/type stabl  ;Определение количества записей в таблице
rtabl tabl2 N dup (<>)      ;Инициализация результирующей таблицы
buf tabl2 <>
    db 10,13,'$'
cou db 3 dup (?)
limsum db ?
temp dw ?
temfam db 10 dup (?),'$'
tempcou db 3 dup (?),'$'
bord2 db '+----------+---+---+---+$'
 
bord db '+----------+---+-----+$'
head2 db '| Surname  |Cou|Sc1|Sc2|$'
 
head1 db '| Фамилия  |Стр|Баллы|$'
 
not1 db 'Введите код страны:$'
not2 db 'Количество выбранных спортсменов и средний балл:$'
;----------------------------------
Nrez dw ?
inst db 10, ?, 10 dup ('$')
 
.code
start:
mov ax,@data        ; Формирование сегмента данных
mov ds,ax           ; 
mov es,ax
cld
;---------------------------------
    mov cx,n
    mov dx,0
    mov ah,0
 
    outstr bord2
    newline
    outstr head2
    newline
    outstr bord2
    newline
    mov bx,0
 
 
    stout:
        outch '|'
        movstr stabl[bx].fam,temfam,10
        outstr temfam
        ;outch '|'
        movstr stabl[bx].count,tempcou,3
        outstr tempcou
        outch '|'
        mov al,stabl[bx].sc1
        outword ax,3
        ;outch '|'
        mov al,stabl[bx].sc2
        outword ax,3
        outch '|'
        newline
        add bx,lens
    loop stout
    outstr bord
    newline
;---------------------------------  
 
    outstr not1
    newline
    lea dx, inst    ;реализация ввода с клавиатуры
    mov ah,0ah
    int 21h
;-----------------------------------
    mov si,dx   ;формирование корректной строки-идентификатора страны
    add si,2
    mov cx,3
    lea di,cou
    rep movsb
;----------------------------------
 
 
    mov cx,n
    mov dx,0
 
    lea si,stabl    ;в si адрес исходной таблицы
    lea di,rtabl    ;в di адрес результата
    
    next:
        cmpstr [si].count, cou, 3   ;сравнить страну с заданной
        
        jne cont    ;если не равно перейти на метку
        mov ah, [si].sc1    ;в ah балл за первую попытку
        add ah,[si].sc2 ;добавить балл за вторую
        movstr [si].fam,[di].fam2,10    ;сформировать вторую таблицу
        movstr [si].count,[di].count2,3
        mov [di].sum, ah    ;заполнить сумму 
        inc dx  ;увеличить dx
        add di,lenr 
    cont:
        add si,lens
        loop next
        mov nrez,dx
        cmp dx,1
        jg beg
        je print
        jmp quit
;_-----------------------------------   
;сортировка
    beg:
        mov cx,nrez ;в счетчик цикла полученное количество отобранных
        dec cx  ;уменьшить счетчик
        mov dx,0
        mov bx,0
    cycle:
 
        mov al, byte ptr rtabl[bx+lenr].sum ;в al сумму следующего элемента
        cmp byte ptr rtabl[bx].sum,al   ;сравнить с суммой текущего элемента
        jle cont1   ;меньше либо равно -) перейти на метку
        
        movstr rtabl[bx],buf,lenr   ;поменять местами элементы если больше
        movstr rtabl[bx+lenr],rtabl[bx],lenr
        movstr buf,rtabl[bx+lenr],lenr
        inc dx
     cont1:
        add bx,lenr ;ставим bx на следующий элемент
        loop cycle  
        
        cmp dx,0
        jnz beg ;если dx не равно 0 переход на метку
     print:
        mov cx, nrez    ;количество отобранных элементов в счетчик
        mov bx,0    ;установка bx на 0
        outstr bord ;вывод таблицы
        newline 
        outstr head1
        newline
        outstr bord
        newline
        mov ah,00
        
     new:
        outch '|'
        movstr rtabl[bx].fam2,temfam,10 ;фамилию на вывод
        
        outstr temfam
        outch '|'
        movstr rtabl[bx].count2,tempcou,3   ;вывести страну
        outstr tempcou
        outch '|'
        
        mov al,rtabl[bx].sum    ;вывести сумму очков
        
        outword ax, 5
        outch '|'
        newline
 
        add bx,lenr
        loop new
        
        outstr bord
    
    mov cx, nrez    ;в счетчик количество отобранных спортсменов
    mov ax,0
    mov bx,0
    mov al,rtabl[bx].sum    ;в al сумму текущего элемента
    cycl1 :
    add bx, lenr    ;переход на следующую строку
    add al,rtabl[bx].sum    ;добавить текущую сумму в al (накопитель суммы)
    loop cycl1
    
;------------------------------------------------------------
    mov bx,nrez
    cmp bx,1    ;если делитель = 1, то пропустить деление
    je lab1
    div bx  
 
    lab1:
    newline
    outstr not2
    newline
    outword nrez
    newline
    outword ax
    outch 32
    outword dx  ;остаток от деления
    outch 47
    outword nrez    
 
 quit:  
    mov     ax,0C07h        ; Function 0Ch = "FLUSH BUFFER AND READ STANDARD INPUT"
    int     21h             ; Waits for a key to be pressed.
    
    mov     ax, 4C00h       ; the exit fuction  [4C+no error (00)]
    int     21h             ; call DOS interrupt 21h
end start
io.asm
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
.XLIST      ;запрет записи этого файла в листинг
 
; файл с макросами ввода-вывода, подключаемый к
; программе по директиве: INCLUDE io.asm
 
;********************************************************************
;       ОКОНЧАНИЕ СЧЕТА ПРОГРАММЫ
;********************************************************************
 
;====================================================================
; Окончание счета программы
;   Обращение: finish
;--------------------------------------------------------------------
finish MACRO
    MOV AX,4C00h
    INT 21h
    ENDM
 
;********************************************************************
;       ВЫВОД НА ЭКРАН (в текстовом режиме)
;********************************************************************
 
;====================================================================
; Переход на новую строку
;   Обращение: newline
;--------------------------------------------------------------------
EXTRN _newline:FAR
newline MACRO
    CALL _newline
    ENDM
 
;====================================================================
; Вывод символа
;   Обращение: outch c
;      где c - i8, r8 или m8
;--------------------------------------------------------------------
outch MACRO c
    PUSH DX
    PUSH AX
    MOV DL,c
    MOV AH,2
    INT 21h
    POP AX
    POP DX
    ENDM
 
;====================================================================
; Вывод строки символов
;   Обращение: outstr
;   На входе: DS:DX - начальный адрес строки
; Замечание: строка должна заканчиваться символом '$', код 36
;--------------------------------------------------------------------
outstr MACRO str
    PUSH AX
    PUSH DX
    LEA DX,str
    MOV AH,9
    INT 21h
    POP DX
    POP AX
    ENDM
 
;====================================================================
; Вывод целого со знаком размером в слово
;   Обращение: outint num [,leng]
;   где num  - выводимое число: i16, r16, m16
;       leng - ширина поля вывода: i8, r8, m8
; Замечание:
;   если поле больше, чем надо, то слева добавляются пробелы,
;   если меньше - выводится только число (полностью)
;   по умолчанию leng=0
;--------------------------------------------------------------------
outint MACRO num,leng
    outnum <num>,<leng>,1
    ENDM
 
;====================================================================
; Вывод целого без знака размером в слово
;   Обращение: outword num [,leng]
;      где num и leng - как в outint
;--------------------------------------------------------------------
outword MACRO num,leng
    outnum <num>,<leng>,0
    ENDM
 
;====================================================================
; Вспомогательный макрос проверки написания имени
; разными (большими и малыми) буквами
;--------------------------------------------------------------------
same MACRO name,variants,ans
    ans=0
    IRP v,<variants>
    IFIDN <name>,<v>
    ans=1
    EXITM
    ENDIF
    ENDM
    ENDM
 
;====================================================================
; Вспомогательный макрос для outint (sign=1) и outword (=0)
;--------------------------------------------------------------------
EXTRN _outnum:FAR
outnum MACRO num,leng,sign
    LOCAL regdx?
    PUSH AX
    PUSH DX
    same <num>,<dx,DX,Dx,dX>,regdx?
    IF regdx?       ;; out DX,leng -->
    IFB <leng>      ;; mov AL,leng
    MOV AL,0        ;; xchg AX,DX
    ELSE
    MOV AL,leng
    ENDIF
    XCHG AX,DX
    ELSE            ;; out num,leng (num<>DX) -->
    IFB <leng>      ;; mov DL,leng
    MOV DL,0        ;; mov AX,num
    ELSE
    MOV DL,leng
    ENDIF
    MOV AX,num
    ENDIF
    MOV DH,sign
    CALL _outnum        ;; AX=num, DL=leng, DH=sign 
    POP DX
    POP AX
    ENDM
 
;********************************************************************
;       ВВОД С КЛАВИАТУРЫ
;********************************************************************
 
;====================================================================
; Очистка буфера ввода с клавиатуры
;   Обращение: flush
;--------------------------------------------------------------------
EXTRN _flush:FAR
flush MACRO
    CALL _flush
    ENDM
 
;====================================================================
; Ввод символа (без Enter)
;   Обращение: inch x
;      где x - r8, m8
;   На выходе: x - введенный символ
;--------------------------------------------------------------------
EXTRN _inch:FAR
inch MACRO x
    LOCAL regax?
    same <x>,<ah,AH,Ah,aH>,regax?
    IF regax?
    XCHG AH,AL      ;;x=AH
    MOV AL,0
    CALL _inch
    XCHG AH,AL
    ELSE
    same <x>,<al,AL,Al,aL>,regax?
    IF regax?
    MOV AL,0        ;;x=AL
    CALL _inch
    ELSE
    PUSH AX         ;;x - не AH и не AL
    MOV AL,0
    CALL _inch
    MOV x,AL
    POP AX
    ENDIF
    ENDIF
    ENDM
 
;====================================================================
; Ввод целого числа (со знаком и без) размером в слово
;   Обращение: inint x
;      где x - r16, m16
;   На выходе: x - введенное число
; Замечание:
;   пропускаются все пробелы и концы строк перед числом;
;   число должно начинаться с цифры, перед ней возможен знак;
;   при минусе число вводится как отрицательное;
;   ввод идет до первой нецифры (в т.ч. до Enter), она глотается;
;   при ошибке будет печатать сообщения и останов программы;
; Ошибки:
;   "нет цифры" - в числе нет ни одной цифры
;   "переполнение" - большое по модулю число
;   (вне отрезка [-32768,+65535])
;--------------------------------------------------------------------
EXTRN _inint:FAR
inint MACRO x
    LOCAL regax?
    same <x>,<ax,AX,Ax,aX>,regax?
    IF regax?
    CALL _inint     ;;x=AX
    ELSE
    PUSH AX         ;;x<>AX
    CALL _inint
    MOV x,AX
    POP AX
    ENDIF
    ENDM
 
;====================================================================
.LIST       ; восстановить запись в листинг
ioproc.asm
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
; Модуль IOPROC: Процедуры ввода-вывода
 
PUBLIC _newline,_outnum,_flush,_inch,_inint
code_seg SEGMENT
     ASSUME CS:code_seg
 
;********************************************************************
;           ВЫВОД НА ЭКРАН
;********************************************************************
 
;====================================================================
; Перевод курсора на новую строку экрана
;   Обращение: CALL _newline
;   Параметров нет
;--------------------------------------------------------------------
_newline PROC FAR
    PUSH DX
    PUSH AX
    MOV AH,2
    MOV DL,13   ; CR (курсор на начало строки)
    INT 21h
    MOV DL,10   ; LF (курсор на следующую строку)
    INT 21h
    POP AX
    POP DX
    RET
_newline ENDP
 
;====================================================================
; Вывод целого числа-слова со знаком или без знака
;   Обращение: CALL _outnum
;   На входе: AX - выводимое число
;         DH - число со знаком (1) или без знака (0)
;         DL - ширина поля вывода (>=0)
;   (если поле больше, чем надо, то слева добавляются пробелы,
;   если меньше - выводится только число)
;--------------------------------------------------------------------
_outnum PROC FAR
    PUSH BP
    MOV BP,SP
    SUB SP,6    ; отвести 6 байтов в стеке под число
    PUSH AX
    PUSH DX
    PUSH SI
    PUSH CX
; учет знака
    CMP DH,1
    JNE Without_Sign    ; переход, если DH <> 1
    CMP AX,0
    JGE Without_Sign    ; переход, если AX >= 0
    MOV DH,2    ; если вывод со знаком и AX < 0,
    NEG AX      ; то DH := 2, AX := ABS(AX)
Without_Sign:
; запись цифр числа в стек (в обратном порядке)
    PUSH DX
    XOR SI,SI   ; SI := 0; SI - кол-во цифр в числе
    MOV CX,10
Next_Digit_Loop:
    MOV DX,0    ; AX -> (DX,AX)
    DIV CX      ; AX = AX div 10, DX = AX mod 10
    ADD DL,'0'
    MOV [BP-6+SI],DL    ; цифра -> стек
    INC SI
    OR AX,AX    ; проверка на ноль (если ноль, установится ZF)
    JNZ Next_Digit_Loop ; переход, если ZF = 0
; запись минуса, если есть, в стек
    POP DX
    CMP DH,2
    JNE Is_Positive     ; переход, если DH <> 2 (если число > 0)
    MOV BYTE PTR [BP-6+SI],'-'
    INC SI
Is_Positive:
; печать пробелов впереди
    MOV CH,0    ; CX - ширина поля вывода
    MOV CL,DL   ;
    MOV AH,2    ; функция 02 прерывания 21h
Print_Next_Space:
    CMP CX,SI
    JLE Print_Number_Loop   ; переход, если ширина (CX) <= длина числа (SI)
    MOV DL,' '
    INT 21h
    DEC CX
    JMP Print_Next_Space
Print_Number_Loop:
; печать (минуса и) цифр
    DEC SI
    MOV DL,[BP-6+SI]
    INT 21h
    OR SI,SI    ; проверка на ноль (если ноль, установится ZF)
    JNZ Print_Number_Loop   ; переход, если ZF = 0
; выход из процедуры
    POP CX
    POP SI
    POP DX
    POP AX
    ADD SP,6
    POP BP
    RET
_outnum ENDP
 
;********************************************************************
;           ВВОД С КЛАВИАТУРЫ
;********************************************************************
 
; буфер ввода с клавиатуры (для работы с функцией 0Ah)
maxb    DB 128      ; макс. размер буфера ввода
sizeb   DB 0        ; число введенных символов в буфере
buf     DB 128 dup(?)   ; сам буфер ввода
posb    DB 0        ; номер послед. считан. символа из buf
 
;====================================================================
; Вспомогательная процедура ввода строки символов
; (включая Enter) в буфер buf (ввод без приглашения)
;--------------------------------------------------------------------
readbuf PROC NEAR
    PUSH AX
    PUSH DX
    PUSH DS
    MOV DX,CS
    MOV DS,DX
    LEA DX,buf-2        ; DS:DX - адрес buf[-2]
    MOV AH,0Ah      ; ввод строки в буфер (включая Enter)
    INT 21h
    CALL _newline       ; курсор на новую строку экрана
    INC CS:sizeb        ; в длине учесть Enter
    MOV CS:posb,0       ; сколько символов уже считано из buf
    POP DS
    POP DX
    POP AX
    RET
readbuf ENDP
 
;====================================================================
; Очистка буфера ввода с клавиатуры
;   Обращение: CALL _flush
;--------------------------------------------------------------------
_flush PROC FAR
    PUSH AX
    MOV CS:sizeb,0      ; очистка buf
    MOV CS:posb,0
    MOV AH,0Ch      ; очистка DOS-буфера
    MOV AL,0
    INT 21h
    POP AX
    RET
_flush ENDP
 
;====================================================================
; Ввод символа (с пропуском или без пропуска Enter)
;   Обращение: CALL _inch
;   На входе: AL - Enter пропустить (0) или выдать как символ (1)
;   На выходе: AL - введенный символ (AH - не меняется)
;--------------------------------------------------------------------
_inch PROC FAR
    PUSH BX
Read_Next_Char:
    MOV BL,CS:posb      ; номер последнего считанного символа
    INC BL          ; след. номер
    CMP BL,CS:sizeb     ; не последний символ буфера?
    JB Read_Char_From_Buffer
    JNE Read_New_String ; буфер не считан до конца?
    CMP AL,0        ; считывать ли конец строки (Enter)?
    JNE Read_Char_From_Buffer
Read_New_String:
    CALL readbuf        ; доввод в буфер
    JMP Read_Next_Char  ; повторить
Read_Char_From_Buffer:
    MOV CS:posb,BL      ; запомнить номер считываемого символа
    MOV BH,0
    MOV AL,CS:buf[BX-1] ; AL:=символ
    POP BX
    RET
_inch ENDP
 
;====================================================================
; Ввод целого числа (со знаком и без) размером в слово
;   Обращение: CALL _inint
;   На входе: нет
;   На выходе: AX - введенное число
;--------------------------------------------------------------------
_inint PROC FAR
    PUSH BX
    PUSH CX
    PUSH DX
; пропуск пробелов и концов строк вначале
Through_Spaces:
    MOV AL,0
    CALL _inch      ; AL - очередной символ (с пропуском Enter)
    CMP AL,' '      ; пробел?
    JE Through_Spaces
; проверка на знак
    MOV DX,0        ; DX - вводимое число
    MOV CX,0        ; CH=0 - нет цифры, CL=0 - плюс
    CMP AL,'+'
    JE Read_Next_Digit
    CMP AL,'-'
    JNE Not_A_Sign
    INC CX          ; CL=1 - минус
; цикл по цифрам
Read_Next_Digit:
    MOV AL,1
    CALL _inch      ; AL - очередной символ (Enter - символ)
Not_A_Sign:         ; проверка на цифру
    CMP AL,'9'
    JA Not_Digit        ; >'9' ?
    SUB AL,'0'
    JB Not_Digit        ; <'0' ?
    MOV CH,1        ; CH=1 - есть цифра
    MOV AH,0
    MOV BX,AX       ; BX - цифра как число
    MOV AX,DX       ; AX - предыдущее число
    MUL CS:prten        ; *10
    JC Overflow_Error   ; >FFFFh (DX<>0) -> переполнение
    ADD AX,BX       ; +цифра
    JC Overflow_Error
    MOV DX,AX       ; спасти число в DX
    JMP Read_Next_Digit ; к след. символу
; кончились цифры (число в DX)
Not_Digit:
    MOV AX,DX
    CMP CH,1        ; были цифры?
    JNE Input_Error
    CMP CL,1        ; был минус?
    JNE Positive_Number
    CMP AX,8000h        ; модуль отриц. числа > 8000h ?
    JA Overflow_Error
    NEG AX          ; взять с минусом
Positive_Number:        ; выход
    POP DX
    POP CX
    POP BX
    RET
prten DW 10
;----------- реакция на ошибки при вводе числа
Overflow_Error:
    LEA CX,err_overflow ; переполнение
    JMP Print_Error_Message
Input_Error:
    LEA CX,err_nodigit  ; нет цифр
Print_Error_Message:        ; печать сообщения об ошибке
    MOV AX,CS
    MOV DS,AX       ; DS=CS
 
    LEA DX,err_msg
    MOV AH,09h      ; outstr
    INT 21h
    MOV DX,CX
    MOV AH,09h      ; outstr
    INT 21h
    CALL _newline
    MOV AH,4Ch      ; finish
    INT 21h
err_msg DB 'Ошибка при вводе числа: ','$'
err_overflow DB 'переполнение','$'
err_nodigit DB 'нет цифры','$'
_inint  ENDP
 
;====================================================================
code_seg ENDS
END         ; конец модуля ioproc
Добавлено через 28 минут 58 секунд
всем спасибо, разобрался... надо директиву jumps указать в начале
1
01.06.2009, 22:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.06.2009, 22:26

Illegal indexing mode и Relative jump out of range
**Error** urkin.asm(111) READW(33) Illegal indexing mode **Error**...

Ошибка "relative jump out of range by 0007h", как исправить?
keypressed: mov AH, 06h ;функция dos mov DL, 0FFh ;ввод символа из буфера...

tasm, "Relative jump out of range "
Подскажите, пожалуйста, что делать в таком случае: при компиляции выскакивает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru