The END directive should not have anything following it. This directive indicates the end of the entire file, not a specific scope, so you don’t need to name the scope.
(Although you can optionally follow END with the name of the entry point procedure, which in your case would be main, this is not necessary and infrequently done in my experience.)
Note that this is in contrast to ENDP (end procedure), which is prefixed with the name of the procedure that is coming to an end (the one started with the PROC directive).
The last three lines should look like this:
IsPrime ENDP ; end the IsPrime procedure
END ; end of the entire file
Your code would be significantly easier to read if you indented the lines according to each’s scope. Moreover, I suspect that would then allow you to find your own «unmatched block nesting» errors.
For example, you would also notice that there is no ENDP directive for the main procedure!
A corrected (and nicely formatted!) version:
INCLUDE Irvine32.inc
.data
org 100h ; set location counter to 100h
.code
;;;;;;;;;;;;;;;;;;;;;;;;
;; Main
;;;;;;;;;;;;;;;;;;;;;;;;
main PROC
jmp CodeStart
DataStart:
max dw " "
space db " ", 0
CodeStart:
mov bx, 1
call IsPrime
cmp dx, 0
LoopStart:
; must be a prime
mov ax, bx
call print_num
; print a space
mov si, offset space
call print_string
add bx, 1
cmp bx, max
jle LoopStart
ret
main ENDP
;;;;;;;;;;;;;;;;;;;;;;;;
;; IsPrime
;;;;;;;;;;;;;;;;;;;;;;;;
IsPrime PROC
; uses a loop to determine if number in bx is prime
; upon return if bx not prime dx will be 0, otherwise dx > 0
; we only have to test divisors from 2 to bx/2
; prepare to divide dx:ax / 2
mov ax, bx
mov dx, 0
mov cx, 2
div cx
; move result into si for loop
mov si, ax
; assume the value is prime
mov dx, 1
; start loop at 2
mov cx, 2
PrimeLoop:
; compare loop count(in cx) and max loop value (in si)
cmp cx, si
; jump out of loop if count(cx) > si
ja StopLabel
; divide test value (in bx) by loop count (in cx)
mov ax, bx
mov dx, 0
div cx
; check remainder (in dx), if zero then we found a divisor
; and the number cannot be prime
cmp dx, 0
; if dx = 0 then we found a divisor and can stop looking
je StopLabel
; increment count
add cx, 1
jmp PrimeLoop
StopLabel:
ret
IsPrime ENDP
END
Если кому интересно предлагаю программку
которая помогает отловить в коде ошибку — A1010
программка заточена под платформу Ассемблера — masm32
Пояснение к программке:
При программировании
компилятор платформы Ассемблера — masm32
в определённых случаях выдаёт ошибку
fatal error A1010:unmatched block nesting : .if-.repeat-.while
суть этой ошибки в том
что компилятор не нашёл закрывающую директиву
к одному из этих высокоуровневых блоков
.if
.endif
.repeat
.until
.while
.endw
но самый большой подводный камень в том
что компилятор конечно пропишет адрес ошибки
но искать эту ошибку по этому адресу
с большой долей вероятности бесполезно
не исключено что это происходит потому что
компилятор попытается найти закрывающую директиву
где то дальше по коду и скорее всего уходит за горизонт
Если проект не большой то найти ошибку будет
относительно не сложно
но если проект большой да ещё в добавок
состоит из нескольких подключённых файлов
то в определённых случаях это может
мягко говоря затормозить процесс кодинга
Ради интереса можно проверить это тестом
например в каком нибудь проекте
в каком нибудь подключённом файле этого проекта
и в какой нибудь прописанной там функции
пропишите в её теле один из этих блоков
например просто блок пустышку
.if eax == 0
.endif
теперь если вы в этом блоке
закоментируете открывающую директиву
;.if eax == 0
.endif
и запустите компилятор то он выдаст ошибку
fatal error A1011:directive must be in control block
вначале этой ошибки — A1011
компилятор укажет вам имя подключённого файла
и номер строки закрывающей директивы — .endif
вольный перевод этой ошибки будет
‘Должна быть открывающая директива блока’
то есть в данном случае директива — .if
Но подобные ошибки компилятор не плохо раскрывает
а вот если вы вместо директивы — .if
закоментируете закрывающую директиву
.if eax == 0
;.endif
то тогда то и всплывёт неприятная ошибка — A1010
где компилятор скажет вам что блок не закрыт
и в большинстве случаев укажет вам бесполезный адрес
а в большом проекте найти эту ошибку
будет мягко говоря не совсем просто
Если вы например работаете с какой нибудь функцией
и случайно допустили там эту ошибку
то найти её будет по горячим следам проще
потому что вы прекрасно знаете
где в данный момент вы только что писали код
а вот если вы случайно или нет допустили эту ошибку
и потом без предварительной компиляции
стали писать какой нибудь другой код
в каком нибудь другом месте или например
отложили написание кода на завтра
то соответственно уже завтра компилятор вас ‘обрадует’
когда выведет вам на обозрение эту ошибку
и не факт что вы сразу догадаетесь где она может быть
это конечно смоделированная ситуация
но она просто показывает как она может изрядно
в некоторых случаях убить драгоценное время и нервы
Алгоритм поиска этой ошибки
в программе реализован так
данные анализируемого файла загоняются в буфер
и программа начинает искать эти сигнатуры
.if
.endif
.while
.endw
.repeat
.until
для каждого из этих трёх блоков
у программы есть три буфера
в который она записывает адрес строки открытия блока
и соответственно закрывает этот адрес
если блок закрывается соответствующей директивой
после прохода всего файла от начала до конца
программа просматривает эти буфера
и если в каком нибудь буфере или буферах
она найдёт открытые адреса строк данного блока
то программа формирует перечень найденных ошибок
и выводит их в окно программы для просмотра
так же в районе правого угла
появляется кнопка значок в виде стрелки
и если вас не устраивает информация в окне
можно кликнуть по этому значку
и тогда программа запишет эту информацию
в файл который будет иметь имя — $error$
и положит его рядом с исполнительным файлом
Программа может отловить и ошибку — A1011
это где компилятор напишет что
должна быть открывающая директива блока
но подобную ошибку и компилятор неплохо находит
по большому счёту эту программу можно использовать
в том случае если ваш компилятор
выдал вам именно ошибку — A1010
с непонятными координатами этой ошибки
Эта программа конечно не панацея
но в определённых случаях может помочь найти ошибку
при анализе она руководствуется только
заложеным в ней алгоритмом и своеобразными фильтрами
но предусмотреть все подводные камни очень сложно
программа работает с указанными сигнатурами
которые могут находиться например в обычном
текстовом файле но в любом случае программа
будет принимать их за чистую монету
или например если ошибка — A1011
будет в сочетании с ошибкой — A1010
то программа может выдать некоректные данные
но в любом случае она может существенно
уменьшить зону поиска проблемы
Если программа всё таки не нашла ошибку
или указала не правильную информацию
то это будет означать что алгоритму программы
не по зубам анализируемый в данный момент файл
Чтобы начать анализ нужно мышкой перетащить
в окно программы файл или папку
если перетащить папку
то программа проанализирует все файлы в этой папке
и если программа найдёт в этой папке
ещё и вложенные папки то программа включит рекурсию
и проанализирует так же все файлы в этих папках
а если перетащить в окно программы файл
то программа проанализирует все файлы
из этой же директории и соответственно
все вложенные папки в ней
Если по определённым причинам
надо проверить только избранные файл или файлы
тогда нужно эти файлы
скопировать в любую пустую папку
и перетащить эту папку в окно программы
У программы установлен лимит
не больше ста (100) файлов
во время поиска в шапке окна
будет прописыватся индикация файлов
Если программе для анализа попадётся бинарный файл
где в одном из байтов будет прописан ноль (0)
то программа естественно проигнорирует этот файл
все остальные бинарные файлы где нет нулей
программа будет анализировать
Если программа не найдёт своим алгоритмом ошибки
то она выведет это сообщение
и покажет количество файлов которые она просмотрела
Как только программа в одном из файлов
найдёт ошибку или ошибки
она сразу же прекратит поиск
и выведет эту информацию в окно программы
с указанием файла где она нашла ошибку или ошибки
ошибки блока — .if
будут первые в списке
ошибки блока — .while
будут вторые в списке
ошибки блока — .repeat
будут третьи в списке
Программа имеет заточку под кодинги
написанные под платформу — masm32
Если кому нибудь это хоть немного интересно
выкладываю ссылку на програмку на яндекс-диске
https://yadi.sk/d/qMdbjlDn3Hqzid
у файла пароль — assch
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
-
assch
Member
- Публикаций:
-
0
- Регистрация:
- 17 мар 2011
- Сообщения:
- 170
Если кому интересно предлагаю программку которая помогает отловить в коде ошибку — 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.176
Писать нужно не в штатном блокноте, а в заточенном под кодинг редакторе и использовать блочные отступы. И никакие выпрямляторы рук не нужны будут
-
Indy_
Well-Known Member
- Публикаций:
-
4
- Регистрация:
- 29 апр 2011
- Сообщения:
- 4.780
rmn,
Писать нужно когда в уме удерживаются начала и концы условных конструкций. Иначе нужны не выпрямляторы» рук, а разума
-
assch
Member
- Публикаций:
-
0
- Регистрация:
- 17 мар 2011
- Сообщения:
- 170
rmn,
не подскажешь такой редактор для — masm32 -
Коцит
Active Member
- Публикаций:
-
0
- Регистрация:
- 31 янв 2017
- Сообщения:
- 130
assch, идея нормальная, но если нужна IDE, могу посоветовать «WinASM Studio». Она как-раз выделяет табами блоки(IF)
Вложения:
-
if.JPG
- Размер файла:
- 50,5 КБ
- Просмотров:
- 645
-
rmn
Well-Known Member
- Публикаций:
-
0
- Регистрация:
- 23 ноя 2004
- Сообщения:
- 2.176
И вообще не понятен смысл такого программистского акта, как комментирование/удаление закрывающего блок тега. Какой еще результат кроме ошибки компиляции тут можно ожидать? Или ТС пишет код последовательно и не знает, что гораздо удобней парные синтаксические элементы (скобки, границы блоков) писать сразу, а потом уже писать между ними код?..
-
assch
Member
- Публикаций:
-
0
- Регистрация:
- 17 мар 2011
- Сообщения:
- 170
rmn,
смысл комментирование/удаление закрывающего блок тега в том чтобы искуственно вызвать эту ошибку (это просто тест неужели не понятно)
и когда компилятор покажет эту ошибку посмотреть на её адрес и убедится что указанный адрес мягко говоря далеко не правильный
Содержание
- What is wrong with this assembly program?
- 6 Answers 6
- Fatal error a1010 unmatched block nesting main
What is wrong with this assembly program?
I am very new to assembly language programming, so it is probably a very obvious error, but.
I use MSVC++, and when I compile any project that has a file with a .asm extension, it uses the rule
And just to make sure the compiler works, I tried the code
But when I compiled it, I get three errors
So I am just wondering, is there some obvious error in part of the code, or is it the compiler thats messing up.
6 Answers 6
You lack a «.code» directive before the code to make MASM know that this is supposed to be in the code segment. Aside from that, you do not RETURN in any way from the code, so the CPU blissfully tries to execute whatever bytes follow as if they were executable code. No wonder it crashes after running.
I asume that the code needs some directives, try this out:
Here, .model says that we’ll use a «small» memory program model and .code says that the following lines are executable code.
EDIT: Ok, there is another example tha should run ok.
From a quick browse, it seems that assembly under VS.NET is uncommon enough that you have to set up custom build rules. You can find an example here: http://www.cs.virginia.edu/
Out of curiosity, what are you trying to accomplish? If you’re just doing this for fun, or to learn assembly language, you’ll probably be better off using a dedicated assembly editor. The MASM32 SDK is one such option. You can then link to the libraries you create from the Visual Studio project.
Источник
Fatal error a1010 unmatched block nesting main

Welcome, Guest. Please login or register.
January 16, 2023, 11:20:16 PM





| The MASM Forum Archive 2004 to 2012 Miscellaneous Forums 16 bit DOS Programming Unmatched block nesting |
« previous next » |
| Pages: [1] 2 | ![]() |
Author |
Topic: Unmatched block nesting (Read 25571 times) |
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
I have an ASM Code Question. I recently downloaded/installed WinAsm Studio and wanted to test a simple Hello World application. When I assembled the code, I got two errors; one of them I fixed by adding an underscore infront of the ‘main proc’ statement.
The other error says: D:Programminghelloworld.asm(18) : fatal error A1010: unmatched block nesting : main
Here is the code:
.model small
.stack
.data
message db "Hello world, I'm learning Assembly !!!", "$"
.code
_main proc
mov ax,seg message
mov ds,ax
mov ah,09
lea dx,message
int 21h
mov ax,4c00h
int 21h
main endp
end main
Can anyone tell me what’s wrong?
It looks like you edited your post, and the line with the error appears to be outside of the code you pasted. Can you paste the entire source?
Ra
Quote:Original post by ajm0528
The other error says: D:Programminghelloworld.asm(18) : fatal error A1010: unmatched block nesting : main
You gave _main to the proc macro and main to endp — they need to match. Just add an underscore there. x)
Just in case you’re not aware, since it seems to come up fairly routinely, the code you have there is 16-bit DOS code. Windows will emulate it for you but it isn’t native Windows code (or any other even vaguely modern OS).
I’m not saying that what you’re doing is completely wasted effort, but a lot of the kind of stuff people usually start doing as a next step from that point (e.g. talking directly to «video memory») either doesn’t work at all or is extremely slow because of the layers of emulation needed to get it to work.
-Mike
Quote:Original post by Anon Mike
Just in case you’re not aware, since it seems to come up fairly routinely, the code you have there is 16-bit DOS code. Windows will emulate it for you but it isn’t native Windows code (or any other even vaguely modern OS).I’m not saying that what you’re doing is completely wasted effort, but a lot of the kind of stuff people usually start doing as a next step from that point (e.g. talking directly to «video memory») either doesn’t work at all or is extremely slow because of the layers of emulation needed to get it to work.
The tutorial I was looking at is most likely really old. I just found it on a search and saw the Hello World program.
Oxyd, when I add the underscore to the second main statement I get these:
Assembling: D:Programmingtestcode.asm
D:Programmingtestcode.asm(19) : error A2006: undefined symbol : main
D:Programmingtestcode.asm(9) : error A2004: symbol type conflict
D:Programmingtestcode.asm(19) : error A2148: invalid symbol type in expression : main
Ok, i put an underscore infront of all the ‘main’ statements and I get this:
D:Programmingtestcode.asm(9) : error A2004: symbol type conflict
which marks this line of code in the editor:
Are you sure ‘seg’ has to be infront of ‘message’? I’m just a beginner but never saw that in my HW program…
[size=»2″]SignatureShuffle: [size=»2″]Random signature images on fora
Quote:Original post by Decrius
Are you sure ‘seg’ has to be infront of ‘message’? I’m just a beginner but never saw that in my HW program…
I tried removing ‘seg’ and I still get errors. Oh well, I was just wanting to mess around with ASM right now but I guess I’ll stick to C++.
Wild stab in the dark, have you tried _message?









Author
Logged
))
. We live and learn. In my meagre defense, I have never used nested PROCs in ASM (I think Delphi treats one as a «local» procedure?).