Доброго Дня Уважаемые Ассемблерщики!!!!Вот уже 3й день бьюсь над такой незадачей ,,,даеться головной асм. файл ;
Assembler | ||
|
Компилирую… компилятор выдает;shell.asm(54): fatal error A1010: unmatched block nesting : Begin_shell
что я не так сделал//////,обьясните нубу кто может……,
-
assch
Member
- Публикаций:
-
0
- Регистрация:
- 17 мар 2011
- Сообщения:
- 178
Если кому интересно предлагаю программку которая помогает отловить в коде ошибку — A1010 программка заточена под платформу Ассемблера — masm32
Пояснение к программке:
При программировании компилятор платформы Ассемблера — masm32 в определённых случаях выдаёт ошибку
fatal error A1010:unmatched block nesting : .if-.repeat-.while
суть этой ошибки в том что компилятор не нашёл закрывающую директиву к одному из этих высокоуровневых блоковно самый большой подводный камень в том, что компилятор конечно пропишет адрес ошибки но искать эту ошибку по этому адресу с большой долей вероятности бесполезно не исключено что это происходит потому, что компилятор попытается найти закрывающую директиву где то дальше по коду и скорее всего уходит за горизонт
Если проект не большой то найти ошибку будет относительно не сложно, но если проект большой да ещё в добавок состоит из нескольких подключённых файлов то в определённых случаях это может мягко говоря затормозить процесс кодинга
Ради интереса можно проверить это тестом например в каком нибудь проекте в каком нибудь подключённом файле этого проекта и в какой нибудь прописанной там функции пропишите в её теле один из этих блоков например просто блок пустышку
теперь если вы в этом блоке закомментируете открывающую директиву
и запустите компилятор то он выдаст ошибку
fatal error A1011:directive must be in control block
вначале этой ошибки — A1011 компилятор укажет вам имя подключённого файла и номер строки закрывающей директивы — .endif
вольный перевод этой ошибки будет: ‘Должна быть открывающая директива блока’, то есть в данном случае директива — .ifНо подобные ошибки компилятор не плохо раскрывает, а вот если вы вместо директивы — .if закоментируете закрывающую директиву
то тогда то и всплывёт неприятная ошибка — A1010, где компилятор скажет вам что блок не закрыт и в большинстве случаев укажет вам бесполезный адрес, а в большом проекте найти эту ошибку будет мягко говоря не совсем просто
Если вы например работаете с какой нибудь функцией и случайно допустили там эту ошибку, то найти её будет по горячим следам проще, потому что вы прекрасно знаете, где в данный момент вы только что писали код, а вот если вы случайно или нет допустили эту ошибку и потом без предварительной компиляции стали писать какой нибудь другой код в каком нибудь другом месте или, например, отложили написание кода на завтра, то соответственно уже завтра компилятор вас ‘обрадует’, когда выведет вам на обозрение эту ошибку и не факт что вы сразу догадаетесь, где она может быть
это конечно смоделированная ситуация, но она просто показывает как она может изрядно в некоторых случаях убить драгоценное время и нервыАлгоритм поиска этой ошибки в программе реализован так данные анализируемого файла загоняются в буфер и программа начинает искать эти сигнатуры
для каждого из этих трёх блоков у программы есть три буфера, в который она записывает адрес строки открытия блока и, соответственно, закрывает этот адрес, если блок закрывается соответствующей директивой после прохода всего файла от начала до конца программа просматривает эти буфера и, если в каком нибудь буфере или буферах она найдёт открытые адреса строк данного блока, то программа формирует перечень найденных ошибок и выводит их в окно программы для просмотра, так же в районе правого угла появляется кнопка значок в виде стрелки и, если вас не устраивает информация в окне, можно кликнуть по этому значку и тогда программа запишет эту информацию в файл который будет иметь имя — $error$ и положит его рядом с исполнительным файлом
Программа может отловить и ошибку — A1011 это где компилятор напишет, что должна быть открывающая директива блока, но подобную ошибку и компилятор неплохо находит по большому счёту эту программу можно использовать в том случае если ваш компилятор выдал вам именно ошибку — A1010 с непонятными координатами этой ошибки
Эта программа конечно не панацея, но в определённых случаях может помочь найти ошибку при анализе она руководствуется только заложенным в ней алгоритмом и своеобразными фильтрами, но предусмотреть все подводные камни очень сложно, программа работает с указанными сигнатурами, которые могут находиться например в обычном текстовом файле, но в любом случае программа будет принимать их за чистую монету или например если ошибка — A1011 будет в сочетании с ошибкой — A1010, то программа может выдать некорректные данные, но в любом случае она может существенно уменьшить зону поиска проблемы
Если программа всё таки не нашла ошибку или указала не правильную информацию, то это будет означать что алгоритму программы не по зубам анализируемый в данный момент файл
Чтобы начать анализ нужно мышкой перетащить в окно программы файл или папку, если перетащить папку, то программа проанализирует все файлы в этой папке и, если программа найдёт в этой папке ещё и вложенные папки, то программа включит рекурсию и проанализирует так же все файлы в этих папках, а если перетащить в окно программы файл, то программа проанализирует все файлы из этой же директории и соответственно все вложенные папки в ней
Если по определённым причинам надо проверить только избранные файл или файлы, тогда нужно эти файлы скопировать в любую пустую папку и перетащить эту папку в окно программы
У программы установлен лимит не больше ста (100) файлов во время поиска в шапке окна будет прописываться индикация файлов
Если программе для анализа попадётся бинарный файл, где в одном из байтов будет прописан ноль (0), то программа естественно проигнорирует этот файл все остальные бинарные файлы где нет нулей программа будет анализировать
Если программа не найдёт своим алгоритмом ошибки, то она выведет это сообщение и покажет количество файлов которые она просмотрела
Как только программа в одном из файлов найдёт ошибку или ошибки она сразу же прекратит поиск и выведет эту информацию в окно программы с указанием файла где она нашла ошибку или ошибки
- ошибки блока — .if будут первые в списке
- ошибки блока — .while будут вторые в списке
- ошибки блока — .repeat будут третьи в списке
Программа имеет заточку под кодинги, написанные под платформу — masm32
Если кому-нибудь это хоть немного интересно, выкладываю ссылку на програмку на яндекс-диске
https://yadi.sk/d/qMdbjlDn3Hqzid
у файла пароль — assch
-
rmn
Well-Known Member
- Публикаций:
-
0
- Регистрация:
- 23 ноя 2004
- Сообщения:
- 2.234
Писать нужно не в штатном блокноте, а в заточенном под кодинг редакторе и использовать блочные отступы. И никакие выпрямляторы рук не нужны будут
-
Indy_
Well-Known Member
- Публикаций:
-
4
- Регистрация:
- 29 апр 2011
- Сообщения:
- 4.775
rmn,
Писать нужно когда в уме удерживаются начала и концы условных конструкций. Иначе нужны не выпрямляторы» рук, а разума
-
assch
Member
- Публикаций:
-
0
- Регистрация:
- 17 мар 2011
- Сообщения:
- 178
rmn,
не подскажешь такой редактор для — masm32 -
Коцит
Active Member
- Публикаций:
-
0
- Регистрация:
- 31 янв 2017
- Сообщения:
- 130
assch, идея нормальная, но если нужна IDE, могу посоветовать «WinASM Studio». Она как-раз выделяет табами блоки(IF)
Вложения:
-
if.JPG
- Размер файла:
- 50,5 КБ
- Просмотров:
- 650
-
rmn
Well-Known Member
- Публикаций:
-
0
- Регистрация:
- 23 ноя 2004
- Сообщения:
- 2.234
И вообще не понятен смысл такого программистского акта, как комментирование/удаление закрывающего блок тега. Какой еще результат кроме ошибки компиляции тут можно ожидать? Или ТС пишет код последовательно и не знает, что гораздо удобней парные синтаксические элементы (скобки, границы блоков) писать сразу, а потом уже писать между ними код?..
-
assch
Member
- Публикаций:
-
0
- Регистрация:
- 17 мар 2011
- Сообщения:
- 178
rmn,
смысл комментирование/удаление закрывающего блок тега в том чтобы искуственно вызвать эту ошибку (это просто тест неужели не понятно)
и когда компилятор покажет эту ошибку посмотреть на её адрес и убедится что указанный адрес мягко говоря далеко не правильный
Here is the assignment:
Write a «menu-driven» program that reads a paragraph from the keyboard and processes it in the following fashion:
Count the number of characters in the paragraph,
Count the number of words,
Count the number of letters that are the same as the third letter of your last name,
Count the number of capital letters.
Terminate the paragraph with special character :
If your last name begins with A,B,C,D,E,F,G,H terminate the paragraph with #,
If your last name begins with I,J,K,L,M,N,O,P terminate the paragraph with %,
If your last name begins with R,S,T,U,V,W,X,Y,Z terminate the paragraph with &,
For this exercise you are required to use subroutines. Read the paragraph in the main procedure;
Process paragraph in subroutines (separate procedure for each count).
Here is my code, I am getting an A1010 error(unmatched block nesting: main) on the last line and I can’t figure out why, please help. I’m using Visual Studio 2015:
include Irvine32.inc
displayMSG MACRO MSG
MOV AH, 09H
LEA DX, MSG
INT 21H
ENDM
.DATA
para DB 100 , ? , 100 DUP('$')
;messages for menu
mes1 DB 0AH, 0DH, 'MENU $'
mes21 DB 0AH, 0DH, '1.COUNT CHARACTERS $'
mes22 DB 0AH, 0DH, '2.COUNT WORDS $'
mes23 DB 0AH, 0DH, '3.COUNT CAPITAL LETTERS $'
mes24 DB 0AH, 0DH, '4.COUNT THIRD LETTER $'
mes25 DB 0AH, 0DH, '5.EXIT $'
mes3 DB 0AH, 0DH, 'ENTER YOUR CHOICE : $'
mes4 DB 0AH, 0DH, 'WRONG CHOICE $'
mes5 DB 0AH, 0DH, 'ENTER THE PARAGRAPH : $'
mes6 DB 0AH, 0DH, 'NUMBER OF CHARACTERS IS : $'
mes7 DB 0AH, 0DH, 'NUMBER OF WORDS $'
mes8 DB 0AH, 0DH, 'NUMBER OF CAPITAL LETTERS $'
mes9 DB 0AH, 0DH, 'NUMBER OF THIRD LETTER $'
.CODE
main PROC
start:
mov ax, @data
mov ds, ax
mov es, ax
displayMSG mes5 ;PROMPT THE USER TO ENTER A PARAGRAPH
mov ah, 0ah ; Accept PARAGRAPH
lea dx, para
int 21h
;DISPLAY MENU TO THE USER
menu :
displayMSG mes1
displayMSG mes21
displayMSG mes22
displayMSG mes23
displayMSG mes24
displayMSG mes25
displayMSG mes3 ; accept choice
mov ah, 01h
int 21h
mov bl, al ; userChoice BL
cmp bl, 31h ; if userChoice=1
je FINDCHAR ; Find NUMBER OF CHARACTERS IN THE STRING
cmp bl, 32h ; if userChoice=2
je FINDWORDS ; FIND NUMBER OF WORDS
cmp bl, 33h ; if userChoice=3
je FINDCAPITAL ; FIND NUMBER OF CAPITAL LETTERS
cmp bl, 34h ; if userChoice=4
je FINDLETTER
cmp bl, 35h ; if userChoice=5
je L1 ; exit
displayMSG mes4 ; Wrong Choice
jmp menu
FINDCHAR:
call FINDCHARPROC
jmp menu
FINDWORDS :
call FINDWORDSPROC
jmp menu
FINDCAPITAL:
call FINDCAPITALSPROC
jmp menu
FINDLETTER :
call FINDTHIRDPROC
jmp menu
L1:
end start
exit
exit
main ENDP
;procedure THAT FINDS NUMBER OF CHARACTERS
FINDCHARPROC proc
displayMSG mes6
mov dl, para+1 ; NUMBER OF CHARACTERS IN THE PARAGRAPH
or dl, 30h
mov ah, 02h ; DISPLAY THE CHARACTERS COUNT
int 21h
ret
FINDCHARPROC ENDP
;find number of WORDS in the paragraph
FINDWORDSPROC proc
mov dl,00h
mov ch, 00h
lea esi, para+2
mov cl, para+1
mov bl,20h ;ASCII value of space
loopAn:
dec cl
cmp cl, 00h
je printWordCount
cmp bl, [esi] ;check if character is space
je incWordCnt
inc esi
jne loopAn
incWordCnt:
inc dl
inc esi
jmp loopAn
printWordCount:
displayMSG mes7
or dl,30h
mov ah,02h
int 21h
ret
FINDWORDSPROC ENDP
;find number of CAPITAL letters in the paragraph
FINDCAPITALSPROC proc
mov dl,00h
mov ch, 00h
lea esi, para+2 ; USER INPUTTED PARAGRAPH
mov cl, para+1
loopAgn:
dec cl
cmp cl, 00h
je printcapitalCount
mov al, byte ptr[esi]
cmp al,"A" ;check if character is capital
jb nextChar
cmp al,"Z" ;check if character is capital
ja nextChar
inc esi
inc dl
jne loopAgn
nextChar:
inc esi
jmp loopAgn
printcapitalCount :
displayMSG mes8
or dl,30h
mov ah,02h
int 21h
ret
FINDCAPITALSPROC ENDP
;count the number of third letter present in the paragraph
FINDTHIRDPROC proc
mov dl,00h
mov ch, 00h
lea esi, para+2 ; DESTINATION STRING
mov cl, para+1
call ReadChar ;get THIRD letter of your name
loopTemp:
dec cl
cmp cl, 00h
je printCount
cmp al, [esi] ;check if character is your third letter
je incCnt
inc esi
jne loopTemp
incCnt:
inc dl
inc esi
jmp loopTemp
printCount :
displayMSG mes9
or dl,30h
mov ah,02h
int 21h
ret
FINDTHIRDPROC ENDP
END main
Search code, repositories, users, issues, pull requests…
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Вот назначение:
Напишите «управляемую меню» программу, которая считывает абзац с клавиатуры и обрабатывает его следующим образом:
Подсчитайте количество символов в абзаце, Подсчитайте количество слов, Подсчитайте количество букв, которые совпадают с третьей буквой вашей фамилии, Подсчитайте количество заглавных букв.
Завершите абзац специальным символом:
Если ваша фамилия начинается с A,B,C,D,E,F,G,H, завершите абзац знаком #,
Если ваша фамилия начинается с I,J,K,L,M,N,O,P, завершите абзац символом%,
Если ваша фамилия начинается с R,S,T,U,V,W,X,Y,Z, завершите абзац знаком &,
Для этого упражнения вы должны использовать подпрограммы. Прочитайте параграф в основной процедуре;
Обработать абзац в подпрограммах (отдельная процедура для каждого отсчета).
Вот мой код, в последней строке я получаю сообщение об ошибке A1010 (непарное вложение блоков: main) и не могу понять почему, пожалуйста, помогите. Я использую Visual Studio 2015:
include Irvine32.inc
displayMSG MACRO MSG
MOV AH, 09H
LEA DX, MSG
INT 21H
ENDM
.DATA
para DB 100 , ? , 100 DUP('$')
;messages for menu
mes1 DB 0AH, 0DH, 'MENU $'
mes21 DB 0AH, 0DH, '1.COUNT CHARACTERS $'
mes22 DB 0AH, 0DH, '2.COUNT WORDS $'
mes23 DB 0AH, 0DH, '3.COUNT CAPITAL LETTERS $'
mes24 DB 0AH, 0DH, '4.COUNT THIRD LETTER $'
mes25 DB 0AH, 0DH, '5.EXIT $'
mes3 DB 0AH, 0DH, 'ENTER YOUR CHOICE : $'
mes4 DB 0AH, 0DH, 'WRONG CHOICE $'
mes5 DB 0AH, 0DH, 'ENTER THE PARAGRAPH : $'
mes6 DB 0AH, 0DH, 'NUMBER OF CHARACTERS IS : $'
mes7 DB 0AH, 0DH, 'NUMBER OF WORDS $'
mes8 DB 0AH, 0DH, 'NUMBER OF CAPITAL LETTERS $'
mes9 DB 0AH, 0DH, 'NUMBER OF THIRD LETTER $'
.CODE
main PROC
start:
mov ax, @data
mov ds, ax
mov es, ax
displayMSG mes5 ;PROMPT THE USER TO ENTER A PARAGRAPH
mov ah, 0ah ; Accept PARAGRAPH
lea dx, para
int 21h
;DISPLAY MENU TO THE USER
menu :
displayMSG mes1
displayMSG mes21
displayMSG mes22
displayMSG mes23
displayMSG mes24
displayMSG mes25
displayMSG mes3 ; accept choice
mov ah, 01h
int 21h
mov bl, al ; userChoice BL
cmp bl, 31h ; if userChoice=1
je FINDCHAR ; Find NUMBER OF CHARACTERS IN THE STRING
cmp bl, 32h ; if userChoice=2
je FINDWORDS ; FIND NUMBER OF WORDS
cmp bl, 33h ; if userChoice=3
je FINDCAPITAL ; FIND NUMBER OF CAPITAL LETTERS
cmp bl, 34h ; if userChoice=4
je FINDLETTER
cmp bl, 35h ; if userChoice=5
je L1 ; exit
displayMSG mes4 ; Wrong Choice
jmp menu
FINDCHAR:
call FINDCHARPROC
jmp menu
FINDWORDS :
call FINDWORDSPROC
jmp menu
FINDCAPITAL:
call FINDCAPITALSPROC
jmp menu
FINDLETTER :
call FINDTHIRDPROC
jmp menu
L1:
end start
exit
exit
main ENDP
;procedure THAT FINDS NUMBER OF CHARACTERS
FINDCHARPROC proc
displayMSG mes6
mov dl, para+1 ; NUMBER OF CHARACTERS IN THE PARAGRAPH
or dl, 30h
mov ah, 02h ; DISPLAY THE CHARACTERS COUNT
int 21h
ret
FINDCHARPROC ENDP
;find number of WORDS in the paragraph
FINDWORDSPROC proc
mov dl,00h
mov ch, 00h
lea esi, para+2
mov cl, para+1
mov bl,20h ;ASCII value of space
loopAn:
dec cl
cmp cl, 00h
je printWordCount
cmp bl, [esi] ;check if character is space
je incWordCnt
inc esi
jne loopAn
incWordCnt:
inc dl
inc esi
jmp loopAn
printWordCount:
displayMSG mes7
or dl,30h
mov ah,02h
int 21h
ret
FINDWORDSPROC ENDP
;find number of CAPITAL letters in the paragraph
FINDCAPITALSPROC proc
mov dl,00h
mov ch, 00h
lea esi, para+2 ; USER INPUTTED PARAGRAPH
mov cl, para+1
loopAgn:
dec cl
cmp cl, 00h
je printcapitalCount
mov al, byte ptr[esi]
cmp al,"A" ;check if character is capital
jb nextChar
cmp al,"Z" ;check if character is capital
ja nextChar
inc esi
inc dl
jne loopAgn
nextChar:
inc esi
jmp loopAgn
printcapitalCount :
displayMSG mes8
or dl,30h
mov ah,02h
int 21h
ret
FINDCAPITALSPROC ENDP
;count the number of third letter present in the paragraph
FINDTHIRDPROC proc
mov dl,00h
mov ch, 00h
lea esi, para+2 ; DESTINATION STRING
mov cl, para+1
call ReadChar ;get THIRD letter of your name
loopTemp:
dec cl
cmp cl, 00h
je printCount
cmp al, [esi] ;check if character is your third letter
je incCnt
inc esi
jne loopTemp
incCnt:
inc dl
inc esi
jmp loopTemp
printCount :
displayMSG mes9
or dl,30h
mov ah,02h
int 21h
ret
FINDTHIRDPROC ENDP
END main