Содержание
- ASM Community
- Ассемблер MASM не видит функции из «Windows API»-ских библиотек
- 1 ответ 1
- Error a2006 undefined symbol messagebox
- Error a2006 undefined symbol messagebox
- Помогите с ассемблером ругается только на call
I just started ASM but I have already started to catch on very easily. For the past 3 days I’ve been stuck on the MessageBox/MessageBoxA function. I cannot get a MessageBox no matter how hard I try. When using the code below, I receive this error at assembly, «error a2006: undefined symbol : MessageBox» & «error a2006: undefined symbol : ExitProcess.» Someone told me it was because the WINAPI.inc include is for 16-bit systems only.
Here’s what I have:
I just looked at the 2 files (WINAPI.inc & WINDOWS.inc) and there are some functions in WINAPI.inc that are required for the program to run that aren’t in WINDOWS.inc but when I try to include both of them I receive this error:
Assembling: C:program.asm.
C:Documents and SettingsAdministratorDesktopSU1.0SourceWINDOWS.inc(73) : error A2111: conflicting parameter definition
C:Documents and SettingsAdministratorDesktopSU1.0SourceWINDOWS.inc(7916) : error A2008: syntax error : offset
C:Documents and SettingsAdministratorDesktopSU1.0Sourceprogram.asm(32) : error A2008: syntax error : in directive
C:Documents and SettingsAdministratorDesktopSU1.0Sourceprogram.asm(99) : error A2006: undefined symbol : MessageBox
C:Documents and SettingsAdministratorDesktopSU1.0Sourceprogram.asm(100) : error A2006: undefined symbol : ExitProcess
C:Documents and SettingsAdministratorDesktopSU1.0Sourceprogram.asm(108) : error A2006: undefined symbol : ExitProcess
I think you have to include either windows.inc or winapi.inc.
The windows.inc file is part of the masm32 package, and only has constants and structures. To declare functions you must use additional include files, also part of the package, one for each dll: user32.inc, kernel32.inc, etc.
I don’t know where does winapi.inc come from, or what it contains, so I can’t help you use it. 🙁
Nevermind I FINALLY figured it out, wow.
Here’s what I did:
Now you can do the same for ExitProcess:
Still I’d recommend you to use hutch’s include files, so you don’t have to do the same for each and every API you want to call. 😯
Источник
Ассемблер MASM не видит функции из «Windows API»-ских библиотек
Изучаю Ассемблер для архитектур x86 Intel-овских процессоров на Windows. Новичок.
Ассемблер MASM не видит функции из «Windows API»-ских библиотек. Вот весь мой код «Hello world»-а через MessageBox. (» .inc «-файлы и прочее использовать не хочу, хочу в деталях самим расписывать и без них делать. Использую не MASM32 из сайта masm32.com, а ml.exe из папки Visual Studio (использую Visual Studio 2019 года. У самого́ Windows 7)).
А консоль выдаёт вот что:
Не понимаю как это решить, чтобы MASM видел что эти функции ( LoadLibraryA , и т.д.) находятся в » kernel32.dll » (на которую в теории должна указывать » kernel32.lib » подключенная с помощью директивы » includelib «)
1 ответ 1
Решил сам. Оказывается просто надо было все функции объявлять с подчёркиванием » _ » в начале имени функции и «собакой» » @ » на конце имени функции после которой указываются количество байт занимаемых параметрами процедуры.
Вот исправленный код объявления их внешними:
И при использовании (например через » call «) тоже надо прописывать их так. Проверял по другому — не работает — писать нужно только так (Windows API-ские функции только, а свои можно хоть как (но надо ли » @ » в своих функциях использовать не знаю)):
А в 64-битной программе эти функции по другому вызываются, без подчёркивания » _ » и без указания собаки » @ » и без указания байт параметров после неё.
Но при передаче в функцию » GetProcAddress » имени функции которую нужно взять из DLL, нужно писать просто имя функции без этих символов.
Только осталась проблема что файл » .exe » сассемблировался не в нужную папку и теперь либо он не сассемблировался, либо его искать надо, но это уже другая тема, не этого вопроса, а сам вопрос решён.
[Решил] Оказывается надо прописать сначала в командной строке путь к папке в которой должен появится файл с помощью » cd «, например » cd «Путь к файлу» «
И, кстати, только что узнал что нужно использовать процедуры с » A » символом на конце, а не » W «, если используешь кавычки ‘ ‘ или » » для вписывания символов в память, иначе будешь получать иероглифы. Но процедуры с » A » символом на конце используются для работы с массивами символов как с 8-битными символами из кодировки ASCII, а процедуры с » W » символом на конце для работы с массивами символов как с 16-битной кодировкой Unicode (которая вроде UTF-16 называется, не помню точно)
Источник
Error a2006 undefined symbol messagebox
Ругается так- D:MYPROGНовая папка(2)Prg_3_1.asm(10) : error A2004: symbol conflict
Подскажите, обьясните причину.
Вот и прога от dorr не компилитя по тем же причинам.
D:MYPROGMass.asm(32) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(35) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(238) : warning A4023: with /coff switch, leading underscore required for start address : start
То- есть, строки
(32)assume ds:@data,es:@data
(35)mov ax, @data
Вот и прога от dorr не компилитя по тем же причинам.
D:MYPROGMass.asm(32) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(35) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(238) : warning A4023: with /coff switch, leading underscore required for start address : start
То- есть, строки
(32)assume ds:@data,es:@data
(35)mov ax, @data
Источник
Error a2006 undefined symbol messagebox
Ругается так- D:MYPROGНовая папка(2)Prg_3_1.asm(10) : error A2004: symbol conflict
Подскажите, обьясните причину.
Вот и прога от dorr не компилитя по тем же причинам.
D:MYPROGMass.asm(32) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(35) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(238) : warning A4023: with /coff switch, leading underscore required for start address : start
То- есть, строки
(32)assume ds:@data,es:@data
(35)mov ax, @data
Вот и прога от dorr не компилитя по тем же причинам.
D:MYPROGMass.asm(32) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(35) : error A2006: undefined symbol : DGROUP
D:MYPROGMass.asm(238) : warning A4023: with /coff switch, leading underscore required for start address : start
То- есть, строки
(32)assume ds:@data,es:@data
(35)mov ax, @data
Источник
Помогите с ассемблером ругается только на call
386
.model flat, stdcall
option casemap :none
include masm32includewindows.inc
include masm32includeuser32.inc
include masm32includekernel32.inc
include masm32includemasm32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
includelib masm32libmasm32.lib
.data
conTitle DB «Sum of integers in array», 0
mes1 DB «Array: «, 0
len_mes1 EQU $-mes1
mes2 DB 0dh, 0ah, «Sum of elements = «, 0
len_mes2 EQU $-mes2
charBuf DB » «, 0
len_charBuf DD $-charBuf
iarray DD -9, 3, -6, 2, 11, -5
larray EQU ($-iarray)/4
ISUM DD 0
lpFmt DB «%d», 0
readBuf DB ?
lenReadBuf DD 1
hStdIn DD 0
hStdOut DD 0
chrsRead DD 0
chrsWritten DD 0
STD_INP_HNDL DD -10
STD_OUTP_HNDL DD -11
.code
start:
call AllocConsole
test EAX, EAX
jz ex
push offset conTitle
call SetConsoleTitleA
test EAX, EAX
jz ex
call GetOut_Hndl
call getInp_hndl
push EBX
mov EBX, offset mes1
mov ECX, len_mes1
call write_con
pop EBX
mov ESI, offset iarray
mov ECX, larray
show_next:
push ESI
push ECX
push DWORD PTR [ESI]
push offset lpFmt
push offset charBuf
call wsprintf
add ESP, 12
push EBX
mov EBX, offset charBuf
mov ECX, len_charBuf
call write_con
pop EBX
call clear_buffer
pop ECX
pop ESI
add ESI, 4
loop show_next
; нахождение суммы элементов массива
mov ECX, larray
mov ESI, offset iarray
finit
fild DWORD PTR [ESI]
next:
fiadd DWORD PTR [ESI+4]
add ESI, 4
loop next
fistp DWORD PTR ISUM
fwait
; преобразование суммы в строку символов
push DWORD PTR ISUM
push offset lpFmt
push offset charBuf
call wsprintf
add ESP, 12
push EBX
mov EBX, offset mes2
mov ECX, len_mes2
call write_con
pop EBX
; вывод значения суммы на экран
push EBX
mov EBX, offset charBuf
mov ECX, len_charBuf
call write_con
pop EBX
call clear_buf
; ожидание ввода с консоли и выход из программы
ошибки только на call
Assembling: C:masm32binwwwwwwww.asm
C:masm32binwwwwwwww.asm(126) : error A2088: END directive required at end of file
C:masm32binwwwwwwww.asm(50) : error A2006: undefined symbol : GET_OUT_HNDL
C:masm32binwwwwwwww.asm(51) : error A2006: undefined symbol : getInp_hndl
C:masm32binwwwwwwww.asm(56) : error A2006: undefined symbol : write_con
C:masm32binwwwwwwww.asm(73) : error A2006: undefined symbol : write_con
C:masm32binwwwwwwww.asm(76) : error A2006: undefined symbol : clear_buf
C:masm32binwwwwwwww.asm(107) : error A2006: undefined symbol : write_con
C:masm32binwwwwwwww.asm(115) : error A2006: undefined symbol : write_con
C:masm32binwwwwwwww.asm(117) : error A2006: undefined symbol : clear_buf
.386
.model flat, stdcall
option casemap :none
include masm32includewindows.inc
include masm32includeuser32.inc
include masm32includekernel32.inc
include masm32includemasm32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
includelib masm32libmasm32.lib
.data
conTitle DB «Sum of integers in array», 0
mes1 DB «Array: «, 0
len_mes1 EQU $-mes1
mes2 DB 0dh, 0ah, «Sum of elements = «, 0
len_mes2 EQU $-mes2
charBuf DB » «, 0
len_charBuf DD $-charBuf
iarray DD -9, 3, -6, 2, 11, -5
larray EQU ($-iarray)/4
ISUM DD 0
lpFmt DB «%d», 0
readBuf DB ?
lenReadBuf DD 1
hStdIn DD 0
hStdOut DD 0
chrsRead DD 0
chrsWritten DD 0
.code
start:
call AllocConsole
test EAX, EAX
jz ex
push offset conTitle
call SetConsoleTitleA
test EAX, EAX
jz ex
Источник
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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
.586P ;Структура для описания дескрипторов сегментов descr struc ; lim dw 0 ;граница (биты 0...15) base_l dw 0 ;база, биты 0...15 base_m db 0 ;база, биты 16...23 attr_1 db 0 ;байт атрибутов 1 attr_2 db 0 ;граница (биты 16...19) и атрибуты 2 base_h db 0 ;база, биты 24...31 descr ends ; ;Структура для описания шлюзов ловушек trap struc ; offs_l dw 0 ;смещение обработчика, биты 0...15 sel dw 16 ;селектор сегмента команд cntr db 0 ;не используется dtype db 8Fh ;тип шлюза - ловушка 80386 и выше offs_h dw 0 ;смещение обработчика, биты 16...31 trap ends ; ;Сегмент данных data segment use16 ;16-разрядный сегмент ;Таблица глобальных дескрипторов GDT gdt_null descr <> ;селектор 0 gdt_data descr <data_size-1,,,92h> ;селектор 8, сегмент данных gdt_code descr <code_size-1,,,98h> ;селектор 16, сегмент команд gdt_stack descr <255,,,92h,,> ;селектор 24, сегмент стека gdt_screen descr <3999,8000h,0Bh,92h> ;селектор 32, видеопамять gdt_size=$-gdt_null ;размер GDT idt label word ;метка начала таблицы дескрипторов исключений trap <exc0> ;дескриптор исключений 0 trap <dummy> ;дескриптор исключений 1 trap <dummy> ;дескриптор исключений 2 trap <exc3> ;дескриптор исключений 3 trap <dummy> ;дескриптор исключений 4 trap <dummy> ;дескриптор исключений 5 trap <dummy> ;дескриптор исключений 6 trap <dummy> ;дескриптор исключений 7 trap <dummy> ;дескриптор исключений 8 trap <dummy> ;дескриптор исключений 9 trap <exc10> ;дескриптор исключений 10 trap <exc11> ;дескриптор исключений 11 trap <exc12> ;дескриптор исключений 12 trap <exc13> ;дескриптор исключений 13 trap <dummy> ;дескриптор исключений 14 trap <dummy> ;дескриптор исключений 16 trap <dummy> ;дескриптор исключений 17 trap <dummy> ;дескриптор исключений 18 idt_size=$-idt ;размер таблицы дескрипторов исключений ;Различные данные программы pdescr df 0 ;псевдодескриптор для команд lgdt и lidt sym db 1 ;символ для вывода на экран attr db 1Eh ;его атрибут msg db 27,'[31;42m Вернулись в реальный режим! ',27,'[0m$' string db '**** ****_**** ****_**** ****' ; 0 5 10 15 20 25 позиция в шаблоне len=$-string data_size=$-gdt_null ;размер сегмента данных data ends ;Сегмент команд text segment use16 ;16-разрядный сегмент assume cs:text,ds:data textseg label word ;метка начала сегмента команд exc0 proc ;обработчик исключения 0 pop eax ;AX = IP mov si,offset string+5 ;выведем адрес call wrd_asc ;возврата на экран mov ax,0 ;для вывода на экран номера исключения jmp home ;на выход exc0 endp exc3 proc ;обработчик исключения 3 pop eax ;AX = IP mov si,offset string+5 ;выведен адрес call wrd_asc ;возврата на экран mov ax,3 ;для вывода на экран номера исключения jmp home ;на выход exc3 endp exc10 proc ;обработчик исключения 10 pop eax ;AX = код ошибки (нам не нужен) pop eax ;AX = IP mov si,offset string+5 ;выведем адрес call wrd_asc ;возврата на экран mov ax,0Ah ;для вывода на экран номера исключения jmp home ;на выход exc10 endp exc11 proc ;обработчик исключения 11 pop eax ;AX = код ошибки (нам не нужен) pop eax ;AX = IP mov si,offset string+5 ;выведем адрес call wrd_asc ;возврата на экран mov ax,0Bh ;для вывода на экран номера исключения jmp home ;на выход exc11 endp exc12 proc ;обработчик исключений 12 pop eax ;AX = код ошибки (нам не нужен) pop eax ;AX = IP mov si,offset string+5 ;выведем адрес call wrd_asc ;возврата на экран mov ax,0Ch ;для вывода на экран номера исключения jmp home ;на выход exc12 endp exc13 proc ;обработчик исключения 13 pop eax ;AX = код ошибки (нам не нужен) pop eax ;AX = IP mov si,offset string+5 ;выведем адрес call wrd_asc ;возврата на экран mov ax,0Dh ;для вывода на экран номера исключения jmp home ;на выход exc13 endp dummy proc ;обработчик остальных исключений mov ax,5555h ;условный код остальных исключений jmp home ;на выход dummy endp main proc ;основная процедура xor eax,eax ;очистим EAX mov ax,data ;загрузим в DS сегментный mov ds,ax ;адрес сегмента данных ;Вычислим и загрузим в GDT линейный адрес сегмента данных shl eax,4 ;EAX=линейный базовый адрес mov ebp,eax ;сохраним его в EBP для будущего mov bx,offset gdt_data ;BX = смещение дескриптора assume bx:ptr descr mov [bx].base_l,ax ;загрузим младшую часть базы shr eax,16 ;старшую половину EAX в AX mov [bx].base_m,al ;загрузим среднюю часть базы ;Вычислим и загрузим в GDT линейный адрес сегмента команд xor eax,4 ;очистим EAX mov ax,cs ;сегментный адрес сегмента команд shl eax,4 ;EAX=линейный базовый адрес mov bx,offset gdt_code ;BX = смещение дескриптора mov [bx].base_l,ax ;загрузим младшую часть базы shr eax,16 ;старшую половину EAX в AX mov [bx].base_m,al ;загрузим среднюю часть базы ;Вычислим и загрузим в GDT линейный адрес сегмента стека xor eax,eax ;очистим EAX mov ax,ss ;сегментный адрес сегмента стека shl eax,4 mov bx,offset gdt_stack mov [bx].base_l,ax shr eax,16 mov [bx].base_m,al ;Подготовим псевдодескриптор pdescr и загрузим регистр GDTR mov dword ptr pdescr+2,ebp ;база GDT mov word ptr pdescr,gdt_size-1 ;граница GDT lgdt pdescr ;загрузим регистр GDTR cli ;запрет аппаратных прерываний ;Загрузим IDTR mov word ptr pdescr,idt_size-1 ;граница xor eax,eax mov ax,offset idt add eax,ebp ;линейный адрес IDT mov dword ptr pdescr+2,eax ;в псевдодескриптор lidt pdescr ;загрузим IDTR ;Переходим в защищённый режим mov eax,cr0 ;получим содержимое регистра CR0 or eax,1 ;установим бит защищённого режима mov cr0,eax ;запишем назад в CR0 ;------------------------------------------------------------------------------; ;Теперь процессор работает в защищённом режиме; ;------------------------------------------------------------------------------; ;Загружаем в CS:IP селектор:смещение точки continue db 0EAh ;код команды FAR JMP dw offset continue ;смещение dw 16 ;селектор сегмента команд continue: ;Делаем адресуемыми данные mov ax,8 ;селектор сегмента данных mov ds,ax ;Делаем адресуемым стек mov ax,24 ;селектор сегмента стека mov ss,ax ;Инициализируем ES mov ax,32 ;селектор сегмента видеобуфера mov es,ax ;инициализируем ES ;Выводим на экран тестовую строку символов mov di,1920 ;начальная позиция на экране mov cx,80 ;число выводимых символов mov ax,word ptr sym ;символ + атрибут scrn: stosw ;содержимое AX на экран inc al ;инкремент символа loop scrn ;цикл mov ax,0FFFFh ;условный код нормального завершения home: mov si,offset string ;точка перехода из обработчика call wrd_asc ;преобразуем AX в символьную строку ;Выведем на экран диагностическую строку mov si,offset string mov cx,len mov ah,74h mov di,1280 scrn1: lodsb stosw loop scrn1 ;Вернёмся в реальный режим ;Сформируем и загрузим дескрипторы для реального режима mov gdt_data.lim,0FFFFh ;граница сегмента данных mov gdt_code.lim,0FFFFh ;граница сегмента команд mov gdt_stack.lim,0FFFFh ;граница сегмента стека mov gdt_screen.lim,0FFFFh ;граница доп.сегмента push ds ;загрузим теневой регистр pop ds ;сегмента данных push ss ;загрузим теневой регистр pop ss ;стека push es ;загрузим теневой регистр pop es ;дополнительного сегмента ;Выполним дальний переход для того, чтобы заново загрузить селектор ;в регистр CS и модифицировать его теневой регистр db 0EAh ;команда дальнего перехода dw offset go ;загрузим теневой регистр dw 16 ;сегмента команд ;Переключим режим процессора go: mov eax,cr0 ;получим содержимое регистра CR0 and eax,0FFFFFFFEh ;сбросим бит защищённого режима mov cr0,eax ;запишем назад в CR0 db 0EAh ;код команды FAR JMP dw offset return ;смещение dw text ;сегмент ;---------------------------------------------------------------------------; ;Теперь процессор снова работает в реальном режиме ; ;---------------------------------------------------------------------------; return: ;Восстановим вычислительную среду реального режима mov ax,data ;сделаем адресуемыми данные mov ds,ax mov ax,stk ;сделаем адресуемым стек mov ss,ax mov sp,256 ;настроим SP ;Восстановим состояние регистра IDTR реального режима mov ax,3FFh ;Граница таблицы векторов (1 Кбайт) mov word ptr pdescr,ax mov eax,0 ;смещение таблицы векторов mov dword ptr pdescr+2,eax lidt pdescr ;загрузим псевдодескриптор в IDTR sti ;разрешим аппаратные прерывания ;Работаем в DOS mov ah,09h ;проверим выполнение функций DOS mov dx,offset string ;после возврата в реальный режим int 21h mov ax,4C00h ;завершим программу обычным образом int 21h main endp ;Инструментальные средства - подпрограммы wrd_asc и bin_asc ;преобразование двоичного числа в символьное 16-ричное представление wrd_asc proc pusha ;сохраним все регистры mov bx,0F000h ;в BX будет маска битов mov dl,12 ;в DL будет число сдвигов AX mov cx,4 ;счётчик цикла cccc: push cx ;сохраним его push ax ;сохраним исходное число в стеке and ax,bx ;выделим четвёрку битов mov cl,dl ;отправим в CL число сдвигов shr ax,cl ;сдвинем на CL бит вправо call bin_asc ;преобразуем в символ ASCII mov byte ptr [si],al ;отправим в строку результата inc si ;сдвинемся по строке вправо pop ax ;вернём в AX исходное число shr bx,4 ;модифицируем маску битов sub dl,4 ;модифицируем число сдвигов pop cx ;восстановим счётчик цикла loop cccc ;цикл popa ;восстановим все регистры ret ;возврат из подпрограммы wrd_asc endp ;Подпрограмма преобразования 16-ричной цифры ;Преобразуемая четвёрка битов в младшей половине AL, результат в AL bin_asc proc cmp al,9 ;цифра больше 9? ja lettr ;да, преобразование в букву add al,30h ;нет преобразуем в символ 0...9 jmp ok ;и на выход из программы lettr: add al,37h ;преобразуем в символ A...F ok: ret ;возврат в вызывающую процедуру bin_asc endp code_size=$-textseg ;размер сегмента команд text ends ;конец сегмента команд ;Сегмент стека stk segment stack use16 ;16-разрядный сегмент db 256 dup ('^') stk ends ;конец сегмента стека end main ;конец программы |
KnowledgeBase Archive
An Archive of Early Microsoft KnowledgeBase Articles
View on GitHub
Article: Q59754
Product(s): Microsoft Macro Assembler
Version(s): 5.1,5.1a
Operating System(s):
Keyword(s):
Last Modified: 06-MAY-2001
-------------------------------------------------------------------------------
The information in this article applies to:
- Microsoft Macro Assembler (MASM), versions 5.1, 5.1a
-------------------------------------------------------------------------------
SYMPTOMS
========
Using the "SEG" directive in conjunction with forward reference to a procedure
or a segment name will produce the error
A2006 : phase error between passes
CAUSE
=====
The assembler incorrectly places a "NOP" instruction in the code generated
during Pass 1. This NOP is not generated in Pass 2, so the assembler generates a
phase error. This phase error will most often happen on the next instruction
that is associated with a fixup.
STATUS
======
Microsoft has confirmed this to be a problem in MASM versions 5.1 and 5.10a.
This problem was fixed in MASM version 6.0.
RESOLUTION
==========
To work around this problem, introduce a NOP that is seen by the assembler only
during the second pass.
MORE INFORMATION
================
The following code produces the errors. The errors do not occur when the ax
register is used. They occur when the bx, cx, and dx registers are used. The
workaround is shown in commented out lines.
Sample Code:
------------
;Assemble options needed: none
;filler MACRO ;macro that codes a nop
; if2 ;in the second pass of the
; nop ;assembler
; endif
;ENDM
_text SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:_TEXT
MOV cx, SEG proc1 ;error using cx, bx or dx
; filler
MOV ax, SEG proc1 ;no error using ax
MOV cx, SEG stackseg ;error using cx, bx, or dx
; filler
MOV ax, SEG stackseg ;no error using ax
STACKSEG SEGMENT PARA PUBLIC 'STACK'
db 100 dup (?)
STACKSEG ENDS
proc1 PROC FAR
ret
proc1 ENDP
_text ENDS
END
Additional query words: 5.10 5.10a buglist5.10 buglist5.10a fixlist6.00
======================================================================
Keywords :
Technology : kbMASMsearch kbAudDeveloper kbMASM510 kbMASM510a
Version : :5.1,5.1a
Solution Type : kbfix
=============================================================================
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS
PROVIDED «AS IS» WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS
ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR
ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL,
CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF
MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION
OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES
SO THE FOREGOING LIMITATION MAY NOT APPLY.
Copyright Microsoft Corporation 1986-2002.
-
dZentle_man
New Member
- Публикаций:
-
0
- Регистрация:
- 24 авг 2008
- Сообщения:
- 414
Блин, весь извелся, никак не пойму почему компилятор не видит функции. При попытке откомпилить выдает следующее:Исходный текст:
-
twgt
New Member
- Публикаций:
-
0
- Регистрация:
- 15 янв 2007
- Сообщения:
- 1.494
http://www.wasm.ru/article.php?article=1001002
Обратить внимание на include! -
dZentle_man
New Member
- Публикаций:
-
0
- Регистрация:
- 24 авг 2008
- Сообщения:
- 414
А че на него обращать то? Все буква в букву, как и там. Статью читал уже. Либо в упор не вижу (тогда может напишешь в чем конкретно косяк?), либо дело не в этом.
-
agrischuk
New Member
- Публикаций:
-
0
- Регистрация:
- 12 янв 2009
- Сообщения:
- 47
Подсказка:
extrn __imp__ExitProcess@4 : dword
ExitProcess equ __imp__ExitProcess@4В книжке, если читать внимательнее приведены inc файлы. Возможно в новом издании еще больше ошибок наделали.
-
mupsy
New Member
- Публикаций:
-
0
- Регистрация:
- 26 ноя 2008
- Сообщения:
- 55
dZentle_man
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
include /masm32/include/shell32.inc
includelib masm32libshell32.lib
includelib masm32libkernel32.lib
includelib masm32libuser32.inc
вот так напиши в начале… -
dZentle_man
New Member
- Публикаций:
-
0
- Регистрация:
- 24 авг 2008
- Сообщения:
- 414
agrischuk, спасибо, помогло. Насчет .inc знаю, но мой компилятор выдает на них сотню ошибок «A2119: language type must be specified», поэтому я решил в этом случае задать все вручную, чтобы хотя бы понять как оно работает. В книжках че попало пишут. Во времена Зубкова еще даже 98-й винды не существовало в природе, поэтому мой компилятор может не поддерживать его пример. У Iczelion’а все завязано на invoke, но invoke особого понимания как все происходит на самом деле не дает — случись ошибка и я не буду знать где ее искать. Собственно на invoke я тоже пробовал завязать, но так ничего и не вышло.
В общем сейчас компилятор функции видит, так что по теме мне помогли. Всем спасибо за внимание
-
Mikl___
Супермодератор
Команда форума- Публикаций:
-
14
- Регистрация:
- 25 июн 2008
- Сообщения:
- 3.468
dZentle_man посмотри здесь
можно сразу писать без «ExitProcess equ __imp__ExitProcess@4»
push ebx
call _imp__ExitProcess@4
тогда достаточно «includelib masm32libkernel32.lib» а строка «include masm32includekernel32.inc» не нужна — это для вызова invoke -
dZentle_man
New Member
- Публикаций:
-
0
- Регистрация:
- 24 авг 2008
- Сообщения:
- 414
Ну я в общем то выбрал средний вариант — в сегменте данных определил импорт функции через equ, в обход .inc файлов. Способ вполне прозрачный и удобнее, чем писать полное имя функции в сегменте кода. За ссылку спасибо, раскурю на досуге.
Очередная программа не хочет собираться, материться и всё тут…
error A2006: undefined symbol : base_l
error A2006: undefined symbol : base_m
Неопределённый символ, но эти символы объявлены, в чём проблема, что не нравится MASM32?
Код программы:
.486P ;разрешение трансляции всех команд Pentium ;Структура для описания дескрипторов сегментов descr struc ;Начало объявления структуры lim dw 0 ;границы (биты 0...15) base_l dw 0 ;база, биты 0...15 base_m db 0 ;база, биты 1...23 attr_1 db 0 ;байт атрибутов 1 attr_2 db 0 ;граница (биты 16...19) и атрибуты 2 base_h db 0 ;база, биты 24...31 descr ends ;конец объявления структуры data segment use16 ;16 - разрядный сегмент ;Таблица глобальных дескрипторов GDT gdt_null descr <0,0,0,0,0,0> ;селектор 0, нулевой дескриптор gdt_data descr <data_size-1,0,0,92h,0,0> ;селектор 8, сегмент данных gdt_code descr <code_size-1,0,0,98h,0,0> ;селектор 16, сегмент команд gdt_stack descr <255,0,0,92h,0,0> ;селектор 24, сегмент стека gdt_screen descr <3999,8000h,0Bh,92h,0,0> ;селектор 32, видеопамять gdt_size=$-gdt_null ;размер GDT ;Различные данные программы pdescr df 0 ;псевдодескриптор для команды lgdt sym db 1 ;символ для вывода на экран attr db 1Eh ;его атрибут msg db 27,'[31;42m Вернулись в реальный режим! ',27,'[0m$' data_size=$-gdt_null ;размер сегмента данных data ends text segment use16 ;16 - разрядный сегмент команд assume cs:text,ds:data main proc xor eax,eax ;очистим EAX mov ax,data ;загрузим в DS сегментный mov ds,ax ;адрес сегмента данных ;Вычислим 32-битовый линейный адрес сегмента данных и загрузим его ;в дескриптор сегмента данных в таблице глобальных дескрипторов GDT shl eax,4 ;EAX=линейный базовый адрес mov ebp,eax ;сохраним его в EBP для будущего mov bx,offset gdt_data ;BX=смещение дескриптора mov [bx].base_l,ax ;загрузим младшую часть базы shr eax,16 ;старшую половину EAX в AX mov [bx].base_m,al ;загрузим среднюю часть базы ;Вычислим и загрузим в GTD линейный адрес сегмента команд xor eax,eax ;очистим EAX mov ax,cs ;сегментный адрес сегмента команд shl eax,4 ;EAX = линейный базовый адрес mov bx,offset gdt_code ;BX = смещение дескриптора mov [bx].base_l,ax ;загрузим младшую часть базы shr eax,16 ;старшую половину EAX в AX mov [bx].base_m,al ;загрузим среднюю часть базы ;Вычислим и загрузим в GTD линейный адрес сегмента стека xor eax,eax ;очистим EAX mov ax,ss ;сегментный адрес сегмента стека shl eax,4 mov bx,offset gdt_stack ; mov [bx].base_l,ax shr eax,16 mov [bx].base_m,al ;Подготовим псевдодескриптор pdescr и загрузим регистр GDTR mov dword ptr pdescr+2,ebp ;база GDT mov word ptr pdescr,gdt_size-1 ;граница GDT lgdt pdescr ;загрузим регистр GDTR ;Подготовимся к возврату из защищённого режима в реальный mov ax,40h ;настроим ES на область mov es,ax ;данных BIOS mov word ptr es:[67h],offset return ;смещение возврата mov es:[69h],cs ;сегмент возврата mov al,0Fh ;выборка байта состояния отключения out 70h,al ;порт КМОП-микросхемы mov al,0Ah ;установка режима восстановления out 71h,al ;в регистре 0Fh сброса процессора cli ;запрет аппаратных прерываний ;Переход в защищённый режим mov eax,cr0 ;получим содержимое регистра CR0 or eax,1 ;установим бит защищённого режима mov cr0,eax ;запишем назад в CR0 ;------------------------------------------------------------------------- ;Теперь процессор работает в защищённом режиме ;------------------------------------------------------------------------- ;Загружаем в CS:IP селектор:смещение точки continue db 0EAh ;код команды FAT JMP dw offset continue ;смещение dw 16 ;селектор сегмента команд continue: ;Делаем адресуемыми данные mov ax,8 ;селектор сегмента данных mov ds,ax ;настроим DS на селектор данных? ;Делаем адресуемым стек mov ax,24 ;селектор сегмента стека mov ss,ax ;Инициализируем ES mov ax,32 ;селектор сегмента видеобуфера mov es,ax ;инициализируем ES ;Выводим на экран тестовую строку символов mov di,1920 ;начальная позиция на экране mov cx,80 ;число выводимых символов mov ax,word ptr sym ;символ+атрибут scrn: stosw ;содержимое AX на экран inc al ;инкремент кода символа loop scrn ;цикл вывода ;----------------------------------------------------------------- ;Вернёмся в реальный режим ;----------------------------------------------------------------- mov al,0FEh ;команда сброса процессора out 64h,al ;в порт 64h hlt ;Останов процессора до окончания сброса ;--------------------------------------------------------------------- ;Теперь процессор снова работает в реальном режиме ;--------------------------------------------------------------------- return: ;Восстановим вычислительную среду реального режима mov ax,data ;сделаем адресуемыми данные mov ds,ax mov ax,stk ;сделаем адресуемым стек mov ss,ax mov sp,256 ;настроим SP sti ;разрешим аппаратные прерывания ;Работаем в DOS mov ah,09h ;проверим выполнение функции DOS mov dx,offset msg ;после возврата в реальный режим int 21h mov ax,4C00h ;завершим программу обычным образом int 21h main endp code_size=$-main ;размер сегмента команд text ends ;Сегмент стека stk segment stack use16 ;16-разрядный сегмент стека db 256 dup ('^') stk ends end main