23:04

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Пришла оценка за гос по ассемблеру: 97. Похоже, что сам экзамен я написала на 100, потому как маген ("защитная" оценка по итогам семестра и внутренним экзаменам) у меня был 94.

Комментарии
18.09.2005 в 23:26

А у тебя, совершенно случайно, нигде не завалялось кода под 16-битный TASM для построчного чтения файла? =) Второй день мучаю =)
19.09.2005 в 00:49

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Именно в виде кода - нет, ей описание необходимых прерываний. Хочешь?

А вообще открою маленький секрет: пишешь прогу на Си, а потом построчно заменяешь инструкции на ассемблерные. Очень хороший способ не запутаться в структуре программы.
19.09.2005 в 01:04

Караидель

Да со структурой-то всё понятно, я себе схемы начертил. На си эту прогу написать - раз плюнуть. А тут нужно всё самому, ручками =) Проблема именно в чтении =) У меня какие-то странные выкрутасы с маркером чтения происходят, например, если его поставить на пятый байт от начала, будет выдавать всякий мусор, которого в файле вообще нет, а если поставить на шестой - всё работает, но не так как надо =)
19.09.2005 в 01:18

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

А не пробовал установить указатель на начало файла и читать побайтово? И вообще, покажи листинг. Может, там у тебя какая ошибка...
19.09.2005 в 01:25

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Посмотри здесь второй исходник - может оказаться что-то полезное...
19.09.2005 в 06:48

Караидель

Ну так я и читаю побайтово. Иду с начала файла побайтово, если встретится символ 13 (0DH, переход), то выходит из цикла. У меня сейчас кода на этой машине нет, но нечто выходит вроде..



Цикл с чтением (работает нормально)

MOV DX,20

SUB DX,CX ;Это чтобы найти количество пройденных символов



Затем маркер ставлю на начало и считываю это количество байт в переменную. Перехожу к следующему.. =)



У нас просто такая система, проходим сейчас ОС и ассемблер. В плане занятий - написание 4 программ. Первую "выпендриться" я сделал достаточно зверскую, ввернул туда прилично логики, условных и безусловных переходов, ввод текста, вывод на экран и т.д. =) А в итоге препод дал мне задание сделать самообучающуюся программу для ответа на вопросы. То есть, ей задают вопрос, она ищет его в файле с данными и выдает на него ответ. Если там нет - просит пользователя ввести ответ и вместе их туда записывает. Вот эту дозапись блок я написал, а чтение - ну что-то не выходит. Ты бы как реализовала хранение данных? Мне на ум ничего кроме построчного хранения ничего не приходит. Там просто парные строки - первая вопрос, вторая ответ, третья вопрос и т.д. =)



Поглядел я ссылку - конечно, интересно, но там почти всё про и под Windows, а книги даже скачать нельзя =(
19.09.2005 в 07:37

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

У тебя строки ограничены по длине? Тогда в чём проблема сразу при побайтовом чтении заполнить место под строчку? Иначе получается, что ты делаешь двойную работу.
19.09.2005 в 10:36

Караидель

Теоретически, они ограничены 20ю символами, но могут быть и меньше.
19.09.2005 в 11:15

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Главное, что не больше. Считывай побайтово в массив. Если у тебя строки неодинакового размера - это будет быстрее, чем поиск конца строки и блоковое чтение. Так что и проблему решишь, и время сэкономишь.
19.09.2005 в 11:24

Не понимаю. Если считывать побайтово по 20 штук, то считаются после короткой строки ещё 10 и 13 символы, а потом начало второй строки.
19.09.2005 в 11:48

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

А ты считывай не 20 штук, а проверяя каждый символ на предмет конца строки. Если нет - запиши в массив и сдвинь указатель, если да - переходи к обработке строки, через простейшие арифметические операции с указателем можно узнать её длину. Просто используй не LOOP, а условные джампы.
19.09.2005 в 18:34

У этого есть две маленькие проблемы =)

Я не знаю, как делать массивы и про арифметические операции не очень понимаю. Как можно из адреса и смещения узнать её длину?
19.09.2005 в 19:27

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

В Ассемблере ты хоть всем дата-сегментом можешь пользоваться как массивом. Например, сделай так:

tmp_str db 20 dup (0)

Т.е. зарезервировать 20 байт памяти, первому из которых соответствует смещение tmp_str, и заполнить нулями.



Арифметические операции тоже очень просты. Предположим, что ты прочитал строку в tmp_str побайтово, пользуясь регистром di в качестве пойнтера.

mov ax,di

sub ax,offset tmp_str

dec ax ;после окончания записи указатель обычно указывает на ячейку (байт, слово) после последнего записаного



Впрочем, можно делать ещё проще: используй индексную адресацию. Т.е. что-то типа tmp_str[di], где di содержит смещение внутри массива.
19.09.2005 в 19:57

Караидель

Нет, всё равно не очень представляю. Допустим, создал на 20 байт памяти, заполнил нулями - это и будет массив? По байтам? Если да, то как обращаться к конкретной ячейке? Извини обилие глупых вопросов, просто после шарпа меня немного угнетает невозможность всё решать проверенными способами =)



Вот, узнать хотел, а нельзя побайтово считывать сразу в строку? То есть, считали байт - записали его в строку в память, проверили - если это 13ый, то скипануть следующий (10ый) и читать в память заново? А то считывание два раза - это как-то неоптимально, мне кажется.



А можно как-то не очень хитро узнать длину файла? Если её знать, то можно ведь создать буффер вроде buffer db ? и туда записать весь считанный файл, он не должен быть большим.
19.09.2005 в 21:00

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Обращаться к ячейке памяти в массиве можно так:

tmp_str[5] или tmp_str+5 - выражения абсолютно одинаковые с точки зрения ассемблера, обращение идёт к шестому байту tmp_str, точнее, шестому после метки (ассемблер не следит за границами массивов).

В адресации можно использовать константные числа и регистры BX, SI, DI, но регистры SI и DI в одном адресе использовать нельзя.



Короче, кусок кода будет примерно такой:

(файл должен быть уже открыт, идентификатор файла - переменная file_id, массив для чтения - tmp_str)

mov di,0

l1:

mov ah,3Fh

mov bx,file_id

mov cx,1

mov dx, offset tmp_str[di]

int 21h

inc di

;обработай байт

;выясни надо ли читать следующий

je l1



А вот как узнавать размер файла я пока что не нашла;о(
19.09.2005 в 21:26

Караидель

Ты мне невероятно помогла =) Спасибо огромное =)
19.09.2005 в 22:22

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Завсегда пожалуйста;о)

Честно, я безумно обожаю шарп, но в ассемблере есть своя прелесть. Это почти дао - думать на языке понятном процессору;о)
20.09.2005 в 15:55

Караидель

Кстати, согласен =) У нас хотя и не программистская кафедра, но базисные знания о системах нам дают. Позволяет краем примазаться к программистам =) Приятно видеть, что в группе несколько человек заинтересовались шарпом и читают книги по нему "для себя". Ассемблер пока не столь популярен =) Нет, дао не подходит - дао не познаваемо =)
20.09.2005 в 16:28

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

А ты попробуй мыслить на ассемблере. Поймёшь, что это тоже непознаваемо;о)
20.09.2005 в 16:42

MOV AH,9

MOV DX,@message

INT 21



message db 'Ну почему же сразу непознаваемо? =)$'
20.09.2005 в 16:49

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

В яблочко!;о)
20.09.2005 в 17:40

Караидель

Слушай, вот вопрос по тому куску кода, который ты привела. Там после проверки идёт условный джамп на новый такт цикла, но ведь вроде бы JE срабатывает именно когда сравнение удачное, когда в флаг кладётся именно нолик? Может, там JNE? У меня просто сейчас некуда заглянуть проверить =)
20.09.2005 в 18:24

Вот так у меня вышло, но проблема в том, что выводит почему-то мусор =(



Search Proc

;--------------Маркер в файле на начало------------------------

MOV AH,42H ; Функция для указания маркера в файле

MOV BX, 5 ; Указание дескриптора (для файла - 5)

MOV AL,0 ; 00 - Счёт ведётся относительно конца файла

MOV CX,0 ; Смещение

MOV DX,0

INT 21H



;-------------Чтение из файла побайтово-------------------------

MOV SI,0

l1:

MOV AH,3FH

MOV BX,5

MOV CX,1

MOV DX,offset readbuf[SI]

INT 21H

INC SI

CMP readbuf[SI],0DH

JNE l1



MOV AH, 40H

MOV BX,1

MOV CX,SI

MOV DX,offset readbuf

INT 21H
20.09.2005 в 18:32

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Ты путаешь... инструкция CMP эквивалентна инструкции SUB с той лишь разницей, что результат нигде не сохраняется. Если результат вычитани равен нулю (операнды равны) - зажигается ZeroFlag, т.е. становится единицей. А JE это тоже самое что и JZ - прыгнуть ксли флаг нуля горит. Кстати, рекомендую иметь под рукой таблицу какие инструкции на какие флаги влияют - совсем необязательно специально проводить сравнение, может, после последнего арифметического действия флаг сам выставляется как надо.
20.09.2005 в 18:37

Караидель

Я проверил, если ставить JE, то он на первом же символе уходит из цикла. Если JNE, то доходит именно до переноса. What's up? =)
20.09.2005 в 20:02

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

а как ты сравниваешь?
20.09.2005 в 20:22

Караидель

Чуть выше я выложил этот кусок кода, ты, наверное, не заметила =)
20.09.2005 в 20:27

Или погоди, ты про то, как проверяю сколько считалось символов? По значению SI. Заставляю его вывести SI символов другой строки, заранее определенной.
20.09.2005 в 20:52

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Artifex

Ой, я идиотка! Конечно же JNE! Проверка четырёхканальных Е1-мультплексоров не способствует мышлению на ассемблере;о)
20.09.2005 в 21:04

Караидель

Да ладно, мне бы твои способности в программировании =) А у тебя нет мыслей, почему тот код вверху не работает? Вроде бы логически всё безупречно. Но это мне так кажется =)