Новичок
Профиль
Группа: Участник
Сообщений: 2
Регистрация: 13.12.2009
Репутация: нет Всего: нет
|
Чужое Задание (его код ниже): Операторы: mov,cmp Адресация: регистровая, непосредственная Директива: db а мое задание операторы: mov,sub,je адресация: регистр-регистр, регистр-память Директива:Dw мучаюсь и не могу понять как это все работает, если не сильно затруднит, помоги мне переделать, уверен проблемма смешная.. вот еще ссылка на другое выполненое задание (команды - mov, sbb. Вид адресации – прямая, по базе, . Директива описания данных - dw) http://pastie.org/741579Исходный текст основного модуля (in.asm) | Код | ;final_SPO_battle sseg segment stack db 256 dup (?) sseg ends dseg segment InputFN db 'input.txt',0 ;имя файла кода outputFN db 'listing.txt',0 ;имя файла кода file db 1024 dup(?) ;строка, в которую записывается файл shcom dw 0 ;счётчик команд output db 1024 dup(?) ;строка, в которую записывается листинг string db 64 dup(?) ;строка, в которой сидит строчка кода lenSTR dw ? ;длина строки кода lenOUT dw 0 ;длина строки, куда выводится ВЕСЬ листинг op_mov db 'mov ' op_cmp db 'cmp ' op_db db ' db ' op_seg db ' segment' op_ends db ' ends' op1 db 32 dup(?) op2 db 32 dup(?) op3 db 32 dup(?) csn db 32 dup(?) ;current segment name len_op1 dw ? len_op2 dw ? len_op3 dw ? len_csn dw ? TSI db 256 dup(?) ;таблица символических имён len_tsi dw ? ;количество имён lnt dw 64 dup(?) ;длина имени в тси ust dw 0 ;used space tsi handle1 dw ? ;хэндл файла кода handle2 dw ? ;хэндл файла листинга point1 dw ? point2 dw ? ;значение байтов начала и конца строки point3 dw ? point4 dw ? ten db 10 chert db 13 enter db 10,13,'$' is_seg_def db 0 titlep db 'Listing:' title_tsi db 'Table of symbolic names:' ErrOpMsg db 'Unable to open file!','$' ErrReMsg db 'Unable to read from file=(','$' ErrEofMsg db 'File is smaller, than a 1024 byte(((','$' JustMsg db 20h,'That is just smile string!',20h,'=)',10,13,'$' decstr db '0123456789' errorMsg db ' - error','$' ErrCrMsg db 'Unable to create listing-file','$' registers db 'ax','al','ah','bx','bl','bh','cx','cl','ch','dx','dl','dh' dig_bin db '0','1','+','-' dig_dec db '0','1','2','3','4','5','6','7','8','9','+','-' dig_hex db '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','+','-' alphavit db '0','1','2','3','4','5','6','7','8','9','q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m' len_dig dw ? kus db 32 dup(?) len_kus dw ? dat db '0000 ','$' dseg ends
cseg segment assume cs:cseg,ds:dseg,ss:sseg start proc far push ds push ax mov bx,dseg mov ds,bx ;для нормальной работы команд обработки строк push ds pop es
mov is_seg_def,0 ;открытие файла input.txt mov ah,3dh mov al,0 lea dx,inputFN int 21h jc ErrOpen mov handle1,ax jmp ok1 ErrOpen: mov ah,9h lea dx,ErrOpMsg int 21h jmp exit ok1:
;чтение из файла в строчку file mov ah,3fh mov bx,handle1 mov cx,1024 lea dx,file int 21h jc ErrRead cmp ax,0 je ErrEOF jmp ok2 ErrRead: mov ah,9h lea dx,ErrReMsg int 21h jmp exit ErrEOf: mov ah,9h lea dx,ErrEofMsg int 21h jmp exit ok2:
;создание файла, куда будет ложится листинг mov ah,3ch mov cx,2 lea dx,outputFN int 21h jc CrErr mov handle2,ax jmp ok3 CrErr: mov ah,9h lea dx,ErrCrMsg int 21h jmp exit ok3:
mov ah,40h mov bx,handle2 mov cx,8 lea dx,titlep int 21h
mov ah,40h mov bx,handle2 mov cx,2 lea dx,enter int 21h
;запись в конец файла символа следующей строки cld lea di,file mov al,00 mov cx,1024 repne scasb lea si,chert dec di movsb lea si,ten movsb
;в di, point1 и point2 учтанавливаем адрес начала файла lea di,file mov point1,di mov point2,di push di
cld cikl: pop di mov al,10 mov cx,1024 repne scasb ;ищем переходы на следущую строчку
;это если файлу конец и дальше только нолики mov ax,[di-1] cmp ax,00 jne lat11 jmp exit
lat11: push di mov ax,point2 mov point1,ax mov point2,di ;dec point2 push point2 mov dx,point1 sub point2,dx mov dx,point2 mov lenSTR,dx pop point2 sub lenSTR,2 lea di,string mov si,point1 mov cx,lenSTR rep movsb ;теперь в string лежит строчка кода
;если строчка оказалась пустой cmp lenSTR,0 je cikl
;перемещаем значения в op3 для вызова процедуры удаления пробелов lea si,string lea di,op3 mov cx,lenstr rep movsb mov bx,lenstr mov len_op3,bx call del_probel_prefix lea si,op3 lea di,string mov cx,len_op3 rep movsb mov bx,len_op3 mov lenstr,bx
;после обработки процедурами строки из пробелов остаётся стрка в один символ пробела lea bx,string cmp byte ptr [bx],20h jne lat16 jmp cikl lat16:
;вывод счётчика команд mov ax,shcom mov bh,10 div bh lea bx, decstr xlat mov dat+2,al mov al,ah xlat mov dat+3,al mov ah,40h mov bx,handle2 mov cx,5 lea dx,dat int 21h
;выводит строчку в файл листинга mov ah,40h mov bx,handle2 mov cx,lenSTR lea dx,string int 21h
call no_comments cmp lenSTR,0 je lat18 call check
lat18: mov ah,40h mov bx,handle2 mov cx,2 lea dx,enter int 21h jmp cikl
exit: mov ah,40h mov bx,handle2 mov cx,2 lea dx,enter int 21h
mov ah,40h mov bx,handle2 mov cx,24 lea dx,title_tsi int 21h
mov ah,40h mov bx,handle2 mov cx,2 lea dx,enter int 21h
call outTSI ret start endp
;ПРОЦЕДУРЫ
;процедура, отвечающая за проверку типа оператора (а заодно- и за правильность операндов) check proc near
;проверяется, записан ли заголовок сегмента cmp is_seg_def,1 je lat12 cmp lenstr,8 ja lat14 call error ret lat14: cld
lea si,string add si,lenstr sub si,8 lea di,op_seg mov cx,8 repe cmpsb je lat13 call error ret lat13: mov is_seg_def,1 mov cx,lenstr sub cx,8 mov len_csn,cx lea si,string lea di,csn rep movsb cld lea si,csn lea di,op3 mov cx,len_csn rep movsb mov ax,len_csn mov len_op3,ax call addTSI jmp exchk
lat12: ;проверка, записан ли заголовок конца сегмента cld lea si,string add si,lenstr sub si,5 lea di,op_ends mov cx,5 repe cmpsb jne lat15
mov cx,len_csn lea si,csn lea di,string repe cmpsb je lat17 call error jmp exchk lat17: mov is_seg_def,0 jmp exchk
lat15: ;метка? mov al,':' lea di,string add di,lenstr dec di cmp al,byte ptr [di] jne lat22
dec lenstr lea si,string lea di,op3 mov cx,lenstr rep movsb
mov ax,lenstr mov len_op3,ax call addTSI jmp exchk
lat22: ; mov? cld add shcom,2 lea di,string lea si,op_mov mov cx,4 repe cmpsb je movcmp sub shcom,2
; cmp? cld inc shcom lea di,string lea si,op_cmp mov cx,4 repe cmpsb je movcmp dec shcom
;директива? cld cmp lenstr,6 jb err mov cx,lenSTR sub cx,4 cikl2: push cx mov bx,lenSTr sub bx,cx sub bx,3 mov cx,4 lea di,string add di,bx lea si,op_db repe cmpsb pop cx je db_chkm loopne cikl2 jmp err
db_chkm: call db_chk ret
err: call error ret
movcmp: ;удаляем приставки cmp и mov cld lea di,string mov si,di add si,4 sub lenstr,4 mov cx,lenstr cmp cx,0 je err rep movsb
;ищем запятую cld mov al,',' lea di,string mov cx,lenSTR repne scasb cmp cx,0 je err cmp cx, lenstr je err push cx
;находим, распределяем адреса по переменным op1 и ор2 cld mov ax,lenstr mov len_op1,ax sub len_op1,cx dec len_op1 lea si,string lea di,op1 mov cx, len_op1 rep movsb
pop cx mov len_op2,cx lea di,op2 lea si,string add si,len_op1 inc si mov cx,len_op2 rep movsb
;перемещаем значения в op3 для вызова процедуры удаления пробелов cld lea si,op1 lea di,op3 mov cx,len_op1 rep movsb mov bx,len_op1 mov len_op3,bx call del_probel_prefix call del_probel_postfix lea si,op3 lea di,op1 mov cx,len_op3 rep movsb mov bx,len_op3 mov len_op1,bx
;перемещаем значения в op3 для вызова процедуры удаления пробелов cld lea si,op2 lea di,op3 mov cx,len_op2 rep movsb mov bx,len_op2 mov len_op3,bx call del_probel_prefix call del_probel_postfix lea si,op3 lea di,op2 mov cx,len_op3 rep movsb mov bx,len_op3 mov len_op2,bx
;проверка длины первого операнда - только 2 байта cmp len_op1,2 je lat10 call error ret lat10:
;проверка первого операнда - регистр? mov ax,word ptr op1 lea di,registers mov cx,12 repne scasw je lat1 call error ret lat1:
;проверка второго операнда - регистр? mov ax,word ptr op2 lea di,registers mov cx,12 repne scasw jne lat2 cmp len_op2,2 je exchk lat2:
;перемещаем значения в op3 для вызова процедуры cld lea si,op2 lea di,op3 mov cx,len_op2 rep movsb mov bx,len_op2 mov len_op3,bx call chk_dig
exchk: ret check endp
;проверка директивы на правильность db_chk proc near ;кидаем название ячейки в op1 cld add cx,3 mov ax,lenSTR mov len_op1,ax sub len_op1,cx lea si,string lea di,op1 mov cx,len_op1 rep movsb
;кидаем остаток после директивы в op2
xor cx,cx mov cx,lenSTr sub cx,len_op1 sub cx,4 mov len_op2,cx lea si,string add si,len_op1 add si,4 lea di,op2 rep movsb
;перемещаем значения в op3 для вызова процедуры удаления пробелов cld lea si,op1 lea di,op3 mov cx,len_op1 rep movsb mov bx,len_op1 mov len_op3,bx call del_probel_postfix lea si,op3 lea di,op1 mov cx,len_op3 rep movsb mov bx,len_op3 mov len_op1,bx
;проверяем, является ли первый символ op1 цифрой lea di,op1 mov al,byte ptr [di] cld lea di,dig_dec mov cx,12 repne scasb jne lat5 call error ret lat5:
;проверяем нет ли лишних символов в названии cld mov cx,len_op1 cikl3: mov bx,len_op1 sub bx,cx lea di,op1 mov al,byte ptr [bx+di] push cx lea di,alphavit mov cx,36 repne scasb pop cx jne lat6 loope cikl3 jmp db_c lat6: call error ret
db_c: ;кидаем название ячейки в ТСИ cld lea si,op1 lea di,op3 mov cx,len_op1 rep movsb call addTSI ;Проверяем выражение директивы db lea di,op2 mov bx,len_op2 mov byte ptr [di+bx],',' inc len_op2 mov byte ptr [di+bx+1],0
;в di, point1 и point2 учтанавливаем адрес начала файла lea di,op2 mov point3,di mov point4,di push di
cikl4: pop di ;это если файлу конец и дальше только нолики mov al,[di] cmp al,00 jne lat9 ret lat9: ;ищем запятые cld mov al,',' mov cx,len_op2 repne scasb push di mov ax,point4 mov point3,ax mov point4,di push point4 mov dx,point3 sub point4,dx mov dx,point4 mov len_kus,dx pop point4 dec len_kus lea di,kus mov si,point3 mov cx,len_op2 rep movsb ;в kus теперь лежит кусок выражения
;перемещаем значения в op3 для вызова процедуры удаления пробелов cld lea si,kus lea di,op3 mov cx,len_kus rep movsb mov bx,len_kus mov len_op3,bx call del_probel_prefix call del_probel_postfix lea si,op3 lea di,kus mov cx,len_op3 rep movsb mov bx,len_op3 mov len_kus,bx
;если две запятые подряд идут cmp len_kus,0 je err1
;для черезчур дальних прыжков jmp rrr long_road: jmp cikl4 rrr:
;прверяет на знак вопроса cmp len_kus,1 jne lat7 lea di,kus cmp byte ptr [di],3Fh je long_road lat7:
;проверяет,на символы cmp len_kus,3 jb lat8 lea di,kus cmp byte ptr [di],27h jne lat8 mov bx,len_kus dec bx cmp byte ptr [di+bx],27h jne lat8 cld mov al,27h lea di,kus inc di mov cx,len_kus sub cx,2 repne scasb jne long_road
lat8: ;перемещаем значения в op3 для вызова процедуры cld lea si,kus lea di,op3 mov cx,len_kus rep movsb mov bx,len_kus mov len_op3,bx call chk_dig je long_road
exit1: pop di ret
err1: pop di call error ret db_chk endp
error proc near mov ah,40h mov bx,handle2 mov cx,8 lea dx,errorMsg int 21h ret error endp
;процедура удаления пробелов в начале строки del_probel_prefix proc near cld mov al,20h lea di,op3 mov cx,len_op3 repe scasb dec di mov si,di lea di,op3 mov len_op3,cx inc len_op3 mov cx,len_op3 rep movsb ret del_probel_prefix endp
;процедура удаления пробелов в конце строки del_probel_postfix proc near std lea di,op3 add di,len_op3 dec di mov al,20h mov cx,len_op3 repe scasb inc cx mov len_op3,cx cld ret del_probel_postfix endp ;определяем тип числа, если определителя нет, по дефолту - десятичное chk_dig proc near lea bx,op3 add bx,len_op3 dec bx cmp byte ptr [bx],'b' je op3_is_bin cmp byte ptr [bx],'h' je op3_is_hex cmp byte ptr [bx],'d' je op3_is_dec inc len_op3 je op3_is_dec
op3_is_dec: lea dx,dig_dec mov len_dig,12 jmp lat3
op3_is_bin: lea dx,dig_bin mov len_dig,4 jmp lat3
op3_is_hex: lea dx,dig_hex mov len_dig,18 jmp lat3
lat3: ;правильно ли записаны числа? dec len_op3 mov cx,len_op3 ;inc cx cikl1: ;dec cx mov bx,len_op3 sub bx,cx lea di,op3 mov al,byte ptr [bx+di] push cx mov di,dx mov cx,len_dig repne scasb pop cx loope cikl1 je exchk_dig call error exchk_dig: ret chk_dig endp
;процедура, удаляющая комментарии no_comments proc near cld mov al,';' lea di,string mov cx,lenstr repne scasb jne exit2 sub lenstr,cx dec lenstr exit2: ret no_comments endp
;процедура, добавляющая строку в ТСИ addTSI proc near ;проверяем, есть ли такие в таблице cmp len_tsi,0 je add_met push len_tsi push ust cld mov cx,len_tsi mov ust,word ptr 0 mov len_tsi,word ptr 0 lat20: push cx lea di,lnt add di,len_tsi xor ax,ax mov al,byte ptr [di] cmp len_op3,ax jne lat21 cld lea si,op3 lea di,tsi add di,ust mov cx,len_op3 repe cmpsb jne lat21 pop cx pop ust pop len_tsi call error ret lat21: lea di,lnt add di,len_tsi xor ax,ax mov al,byte ptr [di] add ust,ax inc len_tsi pop cx loop lat20 pop ust pop len_tsi
add_met: ;добавляем в таблицу cld lea si,op3 lea di,tsi add di,ust mov cx,len_op3 rep movsb mov ax,len_op3 add ust,ax
lea bx,lnt mov di,len_tsi mov ax,len_op3 mov [bx+di],ax inc len_tsi ret addTSI endp
outTSI proc near ;выводим тси mov cx,len_tsi mov ust,word ptr 0 mov len_tsi,word ptr 0 lat19: push cx mov bx,handle2 lea di,lnt add di,len_tsi lea dx,tsi add dx,ust xor ax,ax mov al,byte ptr [di] add ust,ax mov ah,40h xor cx,cx mov cl,byte ptr [di] int 21h inc len_tsi
mov ah,40h mov bx,handle2 mov cx,2 lea dx,enter int 21h pop cx loop lat19 ret outTSI endp
cseg ends end start
|
Это сообщение отредактировал(а) alex999f - 13.12.2009, 22:07
|