Консультация № 186633
26.09.2012, 22:28
0.00 руб.
0 48 1
Здравствуйте! Прошу помощи в следующем вопросе:

Не могу понять почему строка 'pctype is = ' выводится два раза. Я так понимаю проблема со смещением в DX. Но как именно исправить проблему не знаю, может быть вы подскажете. Пользуюсь TASM.
Моя версия изза чего так происходит: Сначала в DX записывается смещение строки 'pctype is = ', затем в DX записывается смещение переменной perem, но эта переменная записывается перед адресом строки и в итоге при выводе через 09h выводится и переменная и строка, как можно сделать так чтобы выводилась только переменная?

Спасибо.

Приложение:
Код:

text segment
assume cs:text, ds:data
begin:
jmp start
;------------------------
TETR_TO_HEX PROC near
and AL,0Fh
cmp AL,09
jbe NEXT
add AL,07
NEXT: add AL,30h
ret
TETR_TO_HEX endp
;-------------------------
BYTE_TO_HEX PROC near
push CX
mov AH,AL
call TETR_TO_HEX
xchg AL,AH
mov CL,4
shr AL,CL
call TETR_TO_HEX ;в AL старшая цифра
pop CX ;в AH младшая цифра
ret
BYTE_TO_HEX endp
;-------------------------
PC_TYPE PROC near
push AX
push DS
push DX
push ES
mov AX, 0F000h
mov ES, AX
mov AL, ES:[0FFFEh]
call BYTE_TO_HEX
mov perem, AX
lea DX, perem
mov AH, 09h
int 21h
pop ES
pop DX
pop DS
pop AX
ret
PC_TYPE endp

start:

mov AX, data
mov DS, AX
lea DX, pctype
mov AH, 09h
int 21h
call PC_TYPE
mov AX, 4C00h
int 21h

text ends
data segment


pctype db 'pctype is = $'
perem dw



data ends
stk segment stack
db 256 dup (0)
stk ends
end begin

Обсуждение

давно
Старший Модератор
31795
6196
27.09.2012, 21:39
общий
27.09.2012, 21:41
Так:
Код:
PC_TYPE PROC near
push AX
push DS
push DX
push ES
mov AX, 0F000h
mov ES, AX
mov AL, ES:[0FFFEh]
call BYTE_TO_HEX
mov perem, AX
pop ES
pop DX
pop DS
pop AX
ret
PC_TYPE endp

start:

mov AX, data
mov DS, AX
call PC_TYPE
lea DX, pctype
mov AH, 09h
int 21h
mov AX, 4C00h
int 21h

text ends
data segment

pctype db 'pctype is = '
perem dw ?
db 'h$'

data ends
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.09.2012, 21:44
общий
https://rfpro.ru/upload/8683 вот пожалуйста
давно
Старший Модератор
31795
6196
27.09.2012, 21:55
общий

Проверьте свой asm-файл, там два раза записана строка.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.09.2012, 21:57
общий
вот он:
а где записана 2 раза?

Код:

text segment
assume cs:text, ds:data
begin:
jmp start
;------------------------
TETR_TO_HEX PROC near
and AL,0Fh
cmp AL,09
jbe NEXT
add AL,07
NEXT: add AL,30h
ret
TETR_TO_HEX endp
;-------------------------
BYTE_TO_HEX PROC near
push CX
mov AH,AL
call TETR_TO_HEX
xchg AL,AH
mov CL,4
shr AL,CL
call TETR_TO_HEX ;в AL старшая цифра
pop CX ;в AH младшая цифра
ret
BYTE_TO_HEX endp
;-------------------------
PC_TYPE PROC near
push AX
push DS
push DX
push ES
mov AX, 0F000h
mov ES, AX
mov AL, ES:[0FFFEh]
call BYTE_TO_HEX
mov perem, AX
lea DX, perem
mov AH, 09h
int 21h
pop ES
pop DX
pop DS
pop AX
ret
PC_TYPE endp

start:

mov AX, data
mov DS, AX
lea DX, pctype
mov AH, 09h
int 21h
call PC_TYPE
mov AX, 4C00h
int 21h

text ends
data segment


pctype db 'pctype is = $'
perem dw



data ends
stk segment stack
db 256 dup (0)
stk ends
end begin
давно
Посетитель
7438
7205
27.09.2012, 21:59
общий
27.09.2012, 22:08
Как я и предполагал (про себя), в Вашей программе в сегменте кода находятся следующие строки:
pctype is = $, после чего 3 нулевых байта. Данные 16 байт дублируются еще раз!
Теперь смотрите, что получается:
1) Вы выводите заголовок. Это начало первой строки.
2) Формируете hex за ней. Это первые из трех нулевых байт за первой строкой.
3) Выводите строку, начиная с них. Следом выводится вся вторая строка!
Вот и получаем заголовок+hex+заголовок!
Почему так получается? Подозреваю, это результат отработки Вашим TASM-ом строки PEREM dw (без знака ?)
Отсюда вопрос: какая у Вас версия Tasm-а? Мой Tasm предупреждает, что он автоматом вставляет ?
Попробуйте добавить знак вопроса...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Старший Модератор
31795
6196
27.09.2012, 22:00
общий
Смотрите рисунок, это дамп Вашего кода(последние строки)
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Старший Модератор
31795
6196
27.09.2012, 22:09
общий
Цитата: Лысков Игорь Витальевич
Отсюда вопрос: какая у Вас версия Tasm-а?

И какие ключи компиляции?

Скачайте TASM 4.10.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.09.2012, 22:10
общий
Turbo Assembler Version 3.1. даже если поставить знак "вопрос" получается то же самое, но это не важно. Спасибо что помогли и простите что время отнял.
Неизвестный
27.09.2012, 22:12
общий
насчёт ключей не знаю, а вот 4.10 сейчас скачаю
давно
Старший Модератор
31795
6196
27.09.2012, 22:15
общий
при компидяции добавьте ключ /l и выложите листинг
tasm name /l
tlink name
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.09.2012, 22:17
общий
Код:

Turbo Assembler Version 4.1 27/09/12 22:17:01 Page 1
prog.asm



1 0000 text segment
2 assume cs:text, ds:data
3 0000 begin:
4 0000 EB 3C 90 jmp start
5 ;------------------------
6 0003 TETR_TO_HEX PROC near
7 0003 24 0F and AL,0Fh
8 0005 3C 09 cmp AL,09
9 0007 76 02 jbe NEXT
10 0009 04 07 add AL,07
11 000B 04 30 NEXT: add AL,30h
12 000D C3 ret
13 000E TETR_TO_HEX endp
14 ;-------------------------
15 000E BYTE_TO_HEX PROC near
16 000E 51 push CX
17 000F 8A E0 mov AH,AL
18 0011 E8 FFEF call TETR_TO_HEX
19 0014 86 C4 xchg AL,AH
20 0016 B1 04 mov CL,4
21 0018 D2 E8 shr AL,CL
22 001A E8 FFE6 call TETR_TO_HEX ;в AL старшая цифра
23 001D 59 pop CX ;в AH младшая цифра
24 001E C3 ret
25 001F BYTE_TO_HEX endp
26 ;-------------------------
27 001F PC_TYPE PROC near
28 001F 50 push AX
29 0020 1E push DS
30 0021 52 push DX
31 0022 06 push ES
32 0023 B8 F000 mov AX, 0F000h
33 0026 8E C0 mov ES, AX
34 0028 26: A0 FFFE mov AL, ES:[0FFFEh]
35 002C E8 FFDF call BYTE_TO_HEX
36 002F A3 000Dr mov perem, AX
37 0032 BA 000Dr lea DX, perem
38 0035 B4 09 mov AH, 09h
39 0037 CD 21 int 21h
40 0039 07 pop ES
41 003A 5A pop DX
42 003B 1F pop DS
43 003C 58 pop AX
44 003D C3 ret
45 003E PC_TYPE endp
46
47 003E start:
48
49 003E B8 0000s mov AX, data
50 0041 8E D8 mov DS, AX
51 0043 BA 0000r lea DX, pctype
52 0046 B4 09 mov AH, 09h
53 0048 CD 21 int 21h
54 004A E8 FFD2 call PC_TYPE
55 004D B8 4C00 mov AX, 4C00h
56 0050 CD 21 int 21h
57
Turbo Assembler Version 4.1 27/09/12 22:17:01 Page 2
prog.asm



58 0052 text ends
59 0000 data segment
60
61
62 0000 70 63 74 79 70 65 20+ pctype db 'pctype is = $'
63 69 73 20 3D 20 24
64 000D ???? perem dw ?
65
66
67
68 000F data ends
69 0000 stk segment stack
70 0000 0100*(00) db 256 dup (0)
71 0100 stk ends
72 end begin
Turbo Assembler Version 4.1 27/09/12 22:17:01 Page 3
Symbol Table




Symbol Name Type Value

??DATE Text "27/09/12"
??FILENAME Text "prog "
??TIME Text "22:17:01"
??VERSION Number 040A
@CPU Text 0101H
@CURSEG Text STK
@FILENAME Text PROG
@WORDSIZE Text 2
BEGIN Near TEXT:0000
BYTE_TO_HEX Near TEXT:000E
NEXT Near TEXT:000B
PCTYPE Byte DATA:0000
PC_TYPE Near TEXT:001F
PEREM Word DATA:000D
START Near TEXT:003E
TETR_TO_HEX Near TEXT:0003

Groups & Segments Bit Size Align Combine Class

DATA 16 000F Para none
STK 16 0100 Para Stack
TEXT 16 0052 Para none
давно
Старший Модератор
31795
6196
27.09.2012, 22:22
общий
27.09.2012, 22:23
интересовал листинг именно 3.1
4.10 всё правильно создал.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.09.2012, 22:26
общий
Код:

Turbo Assembler Version 3.1 27/09/12 22:24:42 Page 1
prog.asm



1 0000 text segment
2 assume cs:text, ds:data
3 0000 begin:
4 0000 EB 3C 90 jmp start
5 ;------------------------
6 0003 TETR_TO_HEX PROC near
7 0003 24 0F and AL,0Fh
8 0005 3C 09 cmp AL,09
9 0007 76 02 jbe NEXT
10 0009 04 07 add AL,07
11 000B 04 30 NEXT: add AL,30h
12 000D C3 ret
13 000E TETR_TO_HEX endp
14 ;-------------------------
15 000E BYTE_TO_HEX PROC near
16 000E 51 push CX
17 000F 8A E0 mov AH,AL
18 0011 E8 FFEF call TETR_TO_HEX
19 0014 86 C4 xchg AL,AH
20 0016 B1 04 mov CL,4
21 0018 D2 E8 shr AL,CL
22 001A E8 FFE6 call TETR_TO_HEX ;в AL старшая цифра
23 001D 59 pop CX ;в AH младшая цифра
24 001E C3 ret
25 001F BYTE_TO_HEX endp
26 ;-------------------------
27 001F PC_TYPE PROC near
28 001F 50 push AX
29 0020 1E push DS
30 0021 52 push DX
31 0022 06 push ES
32 0023 B8 F000 mov AX, 0F000h
33 0026 8E C0 mov ES, AX
34 0028 26: A0 FFFE mov AL, ES:[0FFFEh]
35 002C E8 FFDF call BYTE_TO_HEX
36 002F A3 000Dr mov perem, AX
37 0032 BA 000Dr lea DX, perem
38 0035 B4 09 mov AH, 09h
39 0037 CD 21 int 21h
40 0039 07 pop ES
41 003A 5A pop DX
42 003B 1F pop DS
43 003C 58 pop AX
44 003D C3 ret
45 003E PC_TYPE endp
46
47 003E start:
48
49 003E B8 0000s mov AX, data
50 0041 8E D8 mov DS, AX
51 0043 BA 0000r lea DX, pctype
52 0046 B4 09 mov AH, 09h
53 0048 CD 21 int 21h
54 004A E8 FFD2 call PC_TYPE
55 004D B8 4C00 mov AX, 4C00h
56 0050 CD 21 int 21h
57
Turbo Assembler Version 3.1 27/09/12 22:24:42 Page 2
prog.asm



58 0052 text ends
59 0000 data segment
60
61
62 0000 70 63 74 79 70 65 20+ pctype db 'pctype is = $'
63 69 73 20 3D 20 24
64 000D ???? perem dw ?
65
66
67
68 000F data ends
69 0000 stk segment stack
70 0000 0100*(00) db 256 dup (0)
71 0100 stk ends
72 end begin
Turbo Assembler Version 3.1 27/09/12 22:24:42 Page 3
Symbol Table




Symbol Name Type Value

??DATE Text "27/09/12"
??FILENAME Text "prog "
??TIME Text "22:24:42"
??VERSION Number 030A
@CPU Text 0101H
@CURSEG Text STK
@FILENAME Text PROG
@WORDSIZE Text 2
BEGIN Near TEXT:0000
BYTE_TO_HEX Near TEXT:000E
NEXT Near TEXT:000B
PCTYPE Byte DATA:0000
PC_TYPE Near TEXT:001F
PEREM Word DATA:000D
START Near TEXT:003E
TETR_TO_HEX Near TEXT:0003

Groups & Segments Bit Size Align Combine Class

DATA 16 000F Para none
STK 16 0100 Para Stack
TEXT 16 0052 Para none


но у 4.1 так же pctype is = FC pctype is =
давно
Старший Модератор
31795
6196
27.09.2012, 22:27
общий
Сорри должен бежать, если нужно можно завтра продолжить.
Да ещё вопрос:
Цитата: 394641
Turbo Assembler Version 3.1
где брали(можно ссылку или дистрибутив)?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
27.09.2012, 22:32
общий
хорошо, могу архив скинуть. Нам преподаватель скинул. https://rfpro.ru/upload/8686 вот ссылка
давно
Посетитель
7438
7205
27.09.2012, 22:33
общий
Нашел у себя v3.0 Все нормально!
Остается еще только одно: закачайте свой исходный файл вместе со своим tasm-ом в "мои файлы"...
Есть одна мысль, надо проверим кое-что ...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
27.09.2012, 22:36
общий
Вот это:
"но у 4.1 так же pctype is = FC pctype is ="
говорит о необходимости посмотреть Ваш файл-исходник! TASM не нужен!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.09.2012, 22:37
общий
https://rfpro.ru/upload/8687 вот ссылка на исходник
Неизвестный
27.09.2012, 22:45
общий
у вас он правильно работает?
Неизвестный
27.09.2012, 23:17
общий
А вот ещё интересно, почему нельзя сделать вот так:
Код:

PC_TYPE PROC near
push DS
push DX
push ES
mov AX, 0F000h
mov ES, AX
mov AL, ES:[0FFFEh]
call BYTE_TO_HEX
pop ES
pop DX
pop DS
ret
PC_TYPE endp

start:

mov AX, data
mov DS, AX
call PC_TYPE
lea DX, pctype
mov DX:Dh, AX
mov AH, 09h
int 21h
mov AX, 4C00h
int 21h

text ends
data segment


pctype db 'pctype is = $'
;perem dw
давно
Посетитель
7438
7205
27.09.2012, 23:26
общий
Ура, я понял, в чем дело!
Все дело в Вашем батнике, в котором вызывается линковщик следующей строкой:
tlink /v /x prog.obj prog
Прежде чем читать дальше, посмотрите справку командой tlink /? (из окна cmd)...
Итак, Вы хотели задать имя объектного файла и имя exe-файла.
Но, проблема в том, что эти имена должны отделяться запятой!
Если запятой нет, то два имени воспринимаются, как линковка двух файлов!!!
Другими словами, получается exe-файл, состоящий из двух (!) одинаковых кусков.
Именно поэтому имеем два сегмента данных с двумя строками, кроме того, имеем два одинаковых сегмента кода!
Короче, решение Вашей проблемы:
tlink /v /x prog.obj, prog
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
27.09.2012, 23:32
общий
27.09.2012, 23:46
Вам же надо знать адрес, куда вписать hex! Поэтому удобно иметь переменную.
Хотя можно написать, например, так:
Код:
   call    PC_TYPE
lea DX, pctype
mov word ptr [pctype+12], ax
mov AH, 09h
int 21h
А вот так
Код:
   mov    DX:Dh, AX
нельзя писать!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
27.09.2012, 23:48
общий
Кстати, я ошибся
Надо было mov word ptr [pctype+12], ax
а не mov word ptr [pctype+13], ax
Вот поэтому и лучше иметь метку, чтобы ассемблер сам считал адрес!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.09.2012, 23:48
общий
Спасибо!!! Жесть! конечно я бы никогда не догадался
А разве в DX не лежит адрес pctype, просто прибавить к нему 13 байт и записать... ведь было бы проще если бы можно было так
Код:

mov DX:Dh, AX
давно
Посетитель
7438
7205
27.09.2012, 23:52
общий
Регистр DX нельзя использовать для адресации!
Но, в то же время, он используется для функции 9.
Но можно так:
Код:
   lea   DX, pctype
mov bx, dx
mov word ptr [bx+12], ax
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
27.09.2012, 23:57
общий
Переходите на 32-битный ассемблер
Там для адресации можно использовать любой 32-битный регистр
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.09.2012, 23:59
общий
спасибо вам огромное, люблю в программировании когда всё понятно и логично
Неизвестный
28.09.2012, 00:01
общий
у нас просто по учёбе для 16 битных объясняют и учебник по которому я читаю тоже для 16 битных
давно
Посетитель
7438
7205
28.09.2012, 00:06
общий
16-битный - это начало... И без него никак... Его надо знать :)
А 32-битный - в перспективе, если захочется... Тем более, на дворе давно не 80-е...
Лады, удачи в освоении ассемблера. Если что, обращайтесь
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
28.09.2012, 00:13
общий
хорошо
Форма ответа