Создание интерфейса для алгоритма Юрова

Тема в разделе "WASM.BEGINNERS", создана пользователем NagarD, 8 дек 2011.

  1. NagarD

    NagarD New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2011
    Сообщения:
    4
    Добрый всем вечер

    Я хотел бы узнать как мне "внести" через экран значения в переменные
    Код (Text):
    1. y dt 2.0
    2. x dt -2.0
    И как их вывести результат на экран?
    Я так полагаю что нужно сначала просто выделить место под переменные и уж потом их вносить
    Код (Text):
    1. y dt ?
    2. x dt ?
    Помогите Пожалуйста, уже столько электронок пересмотрел, и ничего не понял.

    Вот Алгоритм Юрова

    Код (Text):
    1. .586p
    2. masm
    3. model user16 small
    4. .stack 100h
    5. .data           ;сегмент данных
    6. flag db 0
    7. p1 dd 0
    8. y dt 2.0        ;основание степини
    9. x dt -2.0       ;показатель степени
    10.  
    11. .code
    12. main:
    13. main proc
    14. ;начало процедуры main
    15.     mov ax, @data
    16.     mov ds, ax
    17.     finit
    18.     fld y
    19.     fld x
    20.     ftst
    21.     fstsw ax
    22.     sahf
    23.     jnc m1          ;перход если х >=0
    24.     jnx flag        ;взведем флаг, если х <0
    25.     fabs            ; |x|
    26. m1: fxch
    27.     fy12x
    28.     fst st(1)
    29.     fabs            ;|z|
    30. ;сравним !z! с единицей
    31.     fld1
    32.     fcom
    33.     fstsw ax
    34.     sahf
    35.     jp exit         ;операнды не сравнимы
    36.     jnc m2          ;если !Z!<1 то переходим на м2
    37.     jz m3           ;если !з!=1 то переходим на м3
    38. ;если "з">1 то приводим к формуле z=z1+z2 ,z1 - целое, z2 - дробное
    39.     or ecx,ecx  ;счетчик вычитаний
    40. m12:inc cx
    41.     fsub st(1), st(0)
    42.     fcom
    43.     fstsw ax
    44.     sahf
    45.     jp exit     ;операнды не сравнимы
    46.     jz m12
    47.     jnc m2      ;если !z! <1, то переходим на m2
    48.     jmp m12     ;если !z! >1, то переходим на m12
    49. m3:mov p1, ecx
    50.     jmp $+7
    51. m2:mov p1, ecx
    52.     fxch
    53.     f2xm1
    54.     fadd        ;компенсируем 1
    55.     fild p1     ;показатель степенидля fscale
    56.     fld1
    57.     fscale
    58.     fxch
    59.     fincstp
    60.     fmul
    61. ;проверка на отрицательную степень
    62.     cmp flag, 1
    63.     jnz exit
    64.     fld1
    65.     fxch
    66.     fdiv
    67. exit:
    68.     mov ax, 4c00h
    69.     int 21h
    70.  
    71. main endp
    72. end main
    Програма под WIN.
     
  2. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Опрос клавиатуры по 9h и 16h (если не изменяет память) прерыванию.
    Посмотри описание.
     
  3. Painter

    Painter New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2011
    Сообщения:
    46
    УСТАНОВКА КУРСОРА
    ------------------------------------------------------------

    Экран можно представить в виде двумерного пространства с
    адресуемыми позициями в любую из которых может быть установ
    лен курсор. Обычный видеомонитор, например, имеет 25 строк
    (нумеруемых от 0 до 24) и 80 столбцов (нумеруемых от 0 до
    79). В следующей таблице приведены некоторые примеры
    положений курсора на экране:

    --------------------------------------------------------
    Дес. формат Шест.формат
    -------------- --------------
    Положение строка столбец строка столбец
    --------------------------------------------------------
    Верхний левый угол 00 00 00 00
    Верхний правый угол 00 79 00 4F
    Центр экрана 12 39/40 00 27/28
    Нижний левый угол 24 00 18 00
    Нижний правый угол 24 79 18 4F
    --------------------------------------------------------

    Команда INT 10H включает в себя установку курсора в любую
    позицию и очистку экрана. Ниже приведен пример установки
    курсора на 5-ую строку и 12-ый столбец:

    MOV AH,02 ;Запрос на установку курсора
    MOV BH,00 ;Экран 0
    MOV DH,05 ;Строка 05
    MOV DL,12 ;Столбец 12
    INT 10H ;Передача управления в BIOS




    Ассемблер для IBM PC. Глава 8 174


    Значение 02 в регистре AH указывает команде INT 10H на выпол
    нение операции установки курсора. Значение строки и столбца
    должны быть в регистре DX, а номер экрана (или страницы) в
    регистре BH (обычно 0). Содержимое других регистров несущест
    венно. Для установки строки и столбца можно также использо
    вать одну команду MOV c непосредственным шест. значением:

    MOV DX,050CH ;Строка 5, столбец 12

    ОЧИСТКА ЭКРАНА
    ------------------------------------------------------------

    Запросы и команды остаются на экране пока не будут смеще
    ны в результате прокручивания ("скролинга") или переписаны
    на этом же месте другими запросами или командами. Когда
    программа начинает cвое выполнение, экран может быть очищен.
    Очищаемая область экрана может начинаться в любой позиции и
    заканчиваться в любой другой позиции с большим номером.
    Начальное значение строки и столбца заносится в регистр DX,
    значение 07 - в регистр BH и 0600H в AX. В следующем примере
    выполняется очистка всего экрана:

    MOV AX,0600H ;AH 06 (прокрутка)
    ;AL 00 (весь экран)
    MOV BH,07 ;Нормальный атрибут (черно/белый)
    MOV CX,0000 ;Верхняя левая позиция
    MOV DX,184FH ;Нижняя правая позиция
    INT 10H ;Передача управления в BIOS

    Значение 06 в регистре AH указывает команде INT 10H на
    выполнение опарации очистки экрана. Эта операция очищает
    экран пробелами; в следующей главе скролинг (прокрутка)
    будет пассмотрен подробнее. Если вы по ошибке установили
    нижнюю правую позицию больше, чем шест. 184F, то очистка
    перейдет вновь к началу экрана и вторично заполнит некоторые
    позиции прробелами. Для монохромных экранов это не вызывает
    каких-либо неприятностей, но для некоторых цветных мониторов
    могут возникнуть серьезные ошибки.

    ЭКРАННЫЕ И КЛАВИАТУРНЫЕ ОПЕРАЦИИ: БАЗОВАЯ ВЕРСИЯ DOS
    ------------------------------------------------------------

    Обычно программы должны выдать на экран сообщение о завер
    шении или об обнаружении ошибки, отобразить запрос для ввода
    данных или для получения указания пользователя. Рассмотрим
    сначала методы, применяемые в базовой версии DOS, в последую
    щих pазделах будут показаны расширенные методы, введенные в
    DOS версии 2.0. Операции из базовой DOS работают во всех
    версиях, хотя в руководстве по DOS рекомендуется применять
    расширенные возможности для новых разработок. В базовой
    версии DOS команды вывода на экран более сложны, но команды
    ввода с клавиатуры проще в использовании, благодаря встроен
    ным проверкам.


    Ассемблер для IBM PC. Глава 8 175



    ВЫВОД НА ЭКРАН: БАЗОВАЯ ВЕРСИЯ DOS
    ------------------------------------------------------------

    Вывод на экран в базовой версии DOS требует определения
    текстового сообщения в области данных, установки в регистре
    AH значения 09 (вызов функциии DOS) и указания команды DOS
    INT 21H. В процессе выполнения операции конец сообщения
    определяется по oграничителю ($), как это показано ниже:

    NAMPRMP DB 'Имя покупателя?','$'
    .
    .
    MOV AH,09 ;Запрос вывода на экран
    LEA DX,NAMPRMP ;Загрузка адреса сообщ.
    INT 21H ;Вызов DOS

    Знак ограничителя "$" можно кодировать непосредственно после
    cимвольной строки (как показано в примере), внутри строки:
    'Имя покупателя?$', или в следующем операторе DB '$'.
    Используя данную операцию, нельзя вывести на экран символ
    доллара "$". Кроме того, если знак доллара будет отсутство
    вать в коце строки, то на экран будут выводиться все
    последующие символы, пока знак "$" не встретиться в памяти.
    Команда LEA загружает адрес области NAMPRMP в регистр DX
    для передачи в DOS адреса выводимой информации. Адрес поля
    NAMPRMP, загружаемый в DX по команде LEA, является oтноси
    тельным, поэтому для вычисления абсолютного адреса данных
    DOS складывает значения регистров DS и DX (DS:lol: X).

    ПРОГРАММА: ВЫВОД НА ЭКРАН НАБОРА СИМВОЛОВ КОДА ASCII
    ------------------------------------------------------------

    Большинство из 256 кодов ASCII имеют символьное представ
    ление, и могут быть выведены на экран. Шест. коды 00 и FF не
    имеют символов и выводятся на экран в виде пробелов, хотя
    символ пробела имеет в ASCII шест. код 20.
    На рис. 8.1 показана COM-программа, которая выводит на
    экран полный набор символов кода ASCII. Программа вызывает
    три процедуры; B10CLR, C10SET и D10DISP. Процедура B10CLR
    очищает экран, а процедура C10SET устанавливает курсор в
    положение 00,00. Процедура D10DISP выводит содержимое поля
    CTR, которое в начале инициализировано значением 00 и затем
    yвеличивается на 1 при каждом выводе на экран, пока не
    достигнет шест. значения FF.

    ------------------------------------------------------------
    ------------------------------------------------------------
    Рис. 8.1. Вывод на экран набора символов кода ASCII

    Так как символ доллара не выводится на экран и кроме того
    коды от шест. 08 до шест. 0D являются специальными
    управляющими cимволами, то это приводит к перемещению


    Ассемблер для IBM PC. Глава 8 176


    курсора и другим управляющим воздействиям. Задание: введите
    программу (рис.8.1), выполните ассемблирование, компановку и
    преобразование в COM-файл. Для запуска программы введите ее
    имя, например, В:ASCII.COM.
    Первая выведенная строка начинается с пробельного символа
    (шест.00), двух "улыбающихся лиц" (шест. 01 и 02) и трех
    карточных символов (шест.03, 04 и 05). Код 07 выдает звуко
    вой сигнал. Код 06 должен отобразиться карточным символом
    "пики", но управляющие символы от шест.08 до 0D сотрут его.
    Код 0D является "возвратом каретки" и приводит к переходу на
    новую (следующую)строку. Код шест.0E - представляется в виде
    музыкальной ноты. Символы после шест. 7F являются графически
    ми.
    Можно изменить программу для обхода управляющих символов.
    Ниже приведен пример фрагмента программы, позволяющий обойти
    все символы между шест. 08 и 0D. Вы можете
    поэкспериментировать, oбходя только, скажем, шест. 08
    (возврат на символ) и 0D (возврат каретки):

    CMP CTR,08H ;Меньше чем 08?
    JB D30 ; да - принять
    CMP CTR,0DH ; Меньше/равно 0D?
    JBE D40 ; да - обойти
    D30:
    MOV AH,40H ;Вывод символов < 08
    ... ; и > 0D
    INT 21H
    D40:
    INC CTR

    ВВОД ДАННЫХ С КЛАВИАТУРЫ: БАЗОВАЯ ВЕРСИЯ DOS
    ------------------------------------------------------------

    Процедура ввода данных с клавиатуры проще, чем вывод на
    экран. Для ввода, использующего базовую DOS, область ввода
    требует наличия cписка параметров, содержащего поля, которые
    необходимы при выполнении команды INT. Во-первых, должна
    быть определена максимальная длина вводимого текста. Это
    необходимо для предупреждения пользователя звуковым сигна
    лом, если набран слишком длинный текст; символы, превышающие
    максимальную длину не принимаются. Во-вторых, в списке
    параметров должно быть определенное поле, куда команда
    возвращает действительную длину введенного текста в байтах.
    Ниже приведен пример, в котором определен список парамет
    ров для области ввода. LABEL представляет собой директиву с
    атрибутом BYTE. Первый байт содержит максимальную длину
    вводимых данных. Так как это однобайтовое поле, то возможное
    максимальное значение его - шест. FF или 255. Второй байт
    необходим DOS для занесения в него действительного числа
    введенных символов. Третьим байтом начинается поле, которое
    будет содержать введенные символы.

    NAMEPAR LABEL BYTE ;Список параметров:


    Ассемблер для IBM PC. Глава 8 177


    MAXLEN DB 20 ; Максимальная длина
    ACTLEN DB ? ; Реальная длина
    NAMEFLD DB 20 DUP (' ') ; Введенные символы

    Так как в списке параметров директива LABEL не занимает
    места, то NAMEPAR и MAXLEN указывают на один и тот же aдрес
    памяти. В трансляторе MASM для определения списка параметров
    в виде структуры может использоваться также директива STRUC.
    Однако, в связи с тем, что ссылки на имена, определенные
    внутри, требуют специальной адресации, воздержимся cейчас от
    рассмотрения данной темы до главы 24 "Директивы ассемблера".
    Для запроса на ввод необходимо поместить в регистр AH
    номер функции - 10 (шест. 0AH), загрузить адрес списка пара
    метров (NAMEPAR в нашем примере) в регистр DX и выполнить
    INT 21H:

    MOV AH,0AH ;Запрос функции ввода
    LEA DX,NAMEPAR ;Загрузить адреса списка параметров
    INT 21H ;Вызвать DOS

    Команда INT ожидает пока пользователь не введет с клавиа
    туры текст, проверяя при этом, чтобы число введенных cимво
    лов не превышало максимального значения, указанного в списке
    параметров (20 в нашем примере). Для указания конца ввода
    пользователь нажимает клавишу Return. Код этой клавиши
    (шест. 0D) также заносится в поле ввода (NAMEFLD в нашем
    примере). Если, например, пользователь ввел имя BROWN
    (Return), то cписок параметров будет содержать информацию:

    дес.: │20│ 5│ В│ R│ O│ W│ N│ #│ │ │ │ │ ...
    шест.: │14│05│42│52│4F│57│4E│0D│20│20│20│20│ ...

    Во второй байт списка параметров (ACTLEN в нашем примере)
    команда заносит длину введенного имени - 05. Код Return
    находится по адресу NAMEFLD +5. Символ # использован здесь
    для индикации конца данных, так как шест. 0D не имеет
    отображаемого символа. Поскольку максимальная длина в 20
    символов включает шест.0D, то действительная длина вводимого
    текста может быть только 19 символов.


    Текст был скопирован и тупо вставлен, поэтому не гарантирую что без ошибок. Разберешься... А вот для того что-бы строку в число перевести, придется попотеть... Посоветую перегнать строку до запятой в десятеричное число и после запятой в него же... Как перегнать строковое представление числа в десятеричное число вы в инете найдете... Придется только отследить где же запятая... Потом при помощи одной интересной команды сопроцессора fbld помещаете в стек сопроцессора оба этих числа (до и после запятой)... то число что после запятой делится на 10 или на 100 или на 1000 и т.д. в зависимости от того сколько в нем знаков(можно делимое получать сразу при перегонке строки после запятой в число вставив в цикл определенные строки и потом поместив его так же как и другие целочисленные переменные в стек сопроцессора) А потом складываются оба числа(то что до запятой и то что после деленное на 10*x). Ну в масме есть еще и макрос FpuAtoFL для перегонки строкового представления числа, но я им не пользовался и говорить не буду. Надеюсь помог. Удачи!
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    перевод числа в строку (правда не работает с "нечислом" и бесконечностью)
    Код (Text):
    1. .686
    2. .model flat
    3. include windows.inc
    4. includelib user32.lib
    5. extern _imp__MessageBoxA@16:dword
    6. .code
    7. start:  fld x
    8.         xchg ebx,eax
    9.         mov edi,offset String
    10.         fldz
    11.         fcomip st,st(1) ;сравниваю число с нулем
    12.         jnz @f
    13.         mov byte ptr [edi],'0'
    14.         jmp b0
    15. @@:     jb @f
    16.         mov al,'-'      ;если отрицательное вывожу знак минус
    17.         stosb
    18.         fchs            ;и получаю модуль числа
    19. @@:     fstcw control   ;устанавливаю режим "округление к нулю"
    20.         or control,0C00h
    21.         fldcw control
    22.         fld st          ;дублирую содержимое st(0) в st(1)
    23.         frndint         ;округляю до целого содержимое st(0)
    24.         fsub st(1),st   ;в st(1) остается дробная часть
    25.         fldz
    26.         fcomip st,st(1) ;сравниваю число с нулем
    27.         jnz @f
    28.         mov al,'0'
    29.         stosb
    30.         jmp b3
    31. @@:     call bcd2str
    32.         fldz
    33. b3:     fcomip st,st(1)
    34.         jz b0
    35.         mov al,'.'
    36.         stosb
    37.         inc ebx
    38.         fmul y          ;умножаю дробную часть на 1.0e17
    39.         call bcd2str
    40. b0:     push 0
    41.         push 0
    42.         push offset String
    43.         push 0
    44.         call _imp__MessageBoxA@16
    45.         retn
    46. bcd2str proc
    47.         fbstp temp
    48.         mov ecx,9       ;в десятом байте информация о знаке числа
    49.         test ebx,ebx
    50.         jnz b1
    51. @@:     cmp byte ptr [ecx-1+temp],0
    52.         jnz b1
    53.         loop @b         ;пропускаем незначащие (нулевые) разряды слева
    54. b1:     mov al,byte ptr [ecx-1+temp];загружаем первую значащую пару разрядов
    55.         cmp al,9        ;если в старшей тетраде 0 - пропустить старшую тетраду
    56.         ja @f
    57.         add al,30h      ;младшую тетраду переводим в ASCII
    58.         stosb
    59.         dec ecx
    60.         jz b2
    61. @@:     movzx ax,byte ptr [ecx-1+temp];распаковываем остальные разряды числа
    62.         ror ax,4        ;выделяем старшую и младшую тетрады
    63.         shr ah,4
    64.         add ax,'00'     ;переводим в ASCII-код
    65.         stosw
    66.         loop @b
    67. b2:     retn
    68. bcd2str endp
    69. x dt -0.123456789;.987654321
    70. control dw ? ;переменная под содержимое регистра CWR
    71. temp dt ?    ;переменная под BCD
    72. y dq 1.0e17  ;множитель
    73. String db 30 dup (0)
    74. end start
    и для преобразования строки в число (код alexcoder, взято здесь)
    Код (Text):
    1. value_s2f       dw      0                       ;переменая для функции преобразования строки в число
    2.  
    3.  
    4. ;+==============================================+
    5. ;|          ПЕРЕВОД ИЗ STRING В FLOAT           |
    6. ;+==============================================+
    7. ;| SI - указатель на строку                     |
    8. ;+----------------------------------------------+
    9. ;| ST(0) - преобрезованное число                |
    10. ;| cf=1 если в строке ошибка                    |
    11. ;+==============================================+
    12. STRTOFLOAT      PROC
    13.         jmp             @STARTCONVERSATION_S2F  ; стартуем в рабочую область
    14. @STARTCONVERSATION_S2F:
    15.         pusha
    16.         mov             value_s2f, 0                    ; обнуляем локальную переменную
    17.         xor             bx, bx                          ; очищаем указатель позиции
    18.         cmp     byte ptr [si], '-'              ; проверяем на отрицательность
    19.         jne             @POSITIVE_S2F           ; число не отрицательное
    20.         inc             bx                                      ; число отрицательное, увеличиваем позицию
    21. @POSITIVE_S2F:
    22.         mov             value_s2f, 10           ; загружаем число в переменную
    23.         fild            value_s2f                       ; загружаем в стэк число 10
    24.         fldz                                                    ; загружаем в стэк число 0
    25. @REPEAT_BEFORE:
    26.         mov             al, byte ptr si[bx]             ; получаем символ
    27.         cmp     al, byte ptr '.'                        ; проверяем точка ли это
    28.         je              @ISPOINTBEFORE  ; точка - идем дальше
    29.         cmp     al, byte ptr 13                 ; проверяем конец ли строкиа
    30.         je              @ENDASINT               ; уже конец и хватит искать дроби
    31.         cmp     al, '0'                         ; если текущий символ не цифра
    32.         jc      @END_S2F_ERR                    ; то выход с ошибкой
    33.         cmp     al,'9'
    34.         ja      @END_S2F_ERR
    35.         sub             al, 30h                         ; делаем из CHAR - INT
    36.         mov             byte ptr value_s2f, al  ; копируем в память
    37.         fiadd   value_s2f                       ; складываем из тем, что есть в стэке
    38.         fmul    st(0), st(1)                    ; умножаем на 10
    39.         inc             bx                                      ; увеличиваем указатель
    40.         jmp             @REPEAT_BEFORE  ; повторяем
    41. @ISPOINTBEFORE:
    42.         inc             bx                                      ; увеличиваем указатель
    43.         fdiv            st(0), st(1)                    ; делим число на 10, т.к. оно уже больше
    44.         fxch            st(1)                           ; меняем местами регистры
    45.         mov             al, byte ptr 13                 ; ищем символ конца строки
    46. @FINDNEXT:
    47.         cmp     si[bx], al                              ; ищем конец строки
    48.         je              @FINDEND                        ; нешел конец строки
    49.         inc             bx                                      ; получаем следующий адрес символа
    50.         jmp             @FINDNEXT                       ; не нашел, еще ищем
    51. @FINDEND:
    52.         dec             bx                                      ; переходим на предыдущий символ
    53.         fldz                                                    ; загружаем в стэк число 0
    54. @REPEAT_AFTER:
    55.         mov             ax, word ptr si[bx]             ; получаем символ
    56.         cmp     al, byte ptr '.'                        ; проверяем точка ли это
    57.         je              @WASPOINTAFTER  ; точка - идем дальше
    58.         cmp     al, '0'                 ; если текущий символ не цифра
    59.         jc      @END_S2F_ERR            ; то выход с ошибкой
    60.         cmp     al,'9'
    61.         ja      @END_S2F_ERR
    62.         sub             al, 30h                         ; делаем из CHAR - INT
    63.         mov             byte ptr value_s2f, al  ; копируем в память
    64.         fiadd   value_s2f                       ; складываем из тем, что есть в стэке
    65.         fdiv            st(0), st(1)                    ; делим на 10
    66.         dec             bx                                      ; декрементируем указатель
    67.         loop    @REPEAT_AFTER   ; повторяем
    68. @WASPOINTAFTER:
    69.         fxch            st(1)                           ; меняем число 10 и остаток местами
    70.         fxch            st(2)                           ; меняем целое и 10 местами
    71.         faddp   st(1)                           ; складываем число до и после запятой
    72.         fxch            st(1)                           ; меняем местами результат и 10
    73.         fistp           value_s2f                       ; извлекаем из стэка 10
    74.         jmp             @FULLEND                        ; полный конец процедуры
    75. @ENDASINT:
    76.         fdiv            st(0), st(1)                    ; делим число на 10, т.к. оно уже больше
    77.         fxch            st(1)                           ; меняем местами регистры
    78.         fistp           value_s2f                       ; извлекаем из стэка 10
    79. @FULLEND:
    80.         cmp     byte ptr [si], '-'              ; проверяем на отрицательность
    81.         jne             @END_S2F                        ; число не отрицательное
    82.         fchs                                                    ; число отрицательное, меняем знак
    83. @END_S2F:
    84.         popa                                            ; выгружаем все регистры
    85.         clc                                             ;ошибки нет
    86.         ret                                                     ; возврат из процедуры
    87.  
    88. @END_S2F_ERR:
    89.         popa                                            ; выгружаем все регистры
    90.         fistp value_s2f                         ;очищаем st0
    91.         stc                                     ;ошибка
    92.         ret                                                     ; возврат из процедуры
    93. STRTOFLOAT      ENDP
     
  5. NagarD

    NagarD New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2011
    Сообщения:
    4
    Код (Text):
    1. .586p
    2. ;masm
    3. .model small
    4. .stack 100h
    5. .data                   ;сегмент данных
    6. flag db 0
    7. p1 dd 0
    8. y dt 2.0                ;основание степини
    9. x dt -2.0               ;показатель степени
    10.  
    11. .code
    12. main:
    13. main proc               ;начало процедуры main
    14.     mov ax, @data
    15.     mov ds, ax
    16.     finit
    17.     fld y
    18.     fld x
    19.     ftst
    20.     fstsw ax
    21.     sahf
    22.     jnc m1              ;перход если х >=0
    23.     inc flag            ;взведем флаг, если х <0
    24.     fabs                ; |x|
    25. m1: fxch
    26.     fyl2x
    27.     fst st(1)
    28.     fabs                ;|z|
    29. ;сравним !z! с единицей
    30.     fld1
    31.     fcom
    32.     fstsw ax
    33.     sahf
    34.     jp exit             ;операнды не сравнимы
    35.     jnc m2              ;если !Z!<1 то переходим на м2
    36.     jz m3               ;если !з!=1 то переходим на м3
    37. ;если "з">1 то приводим к формуле z=z1+z2 ,z1 - целое, z2 - дробное
    38.     or ecx,ecx          ;счетчик вычитаний
    39. m12:inc cx
    40.     fsub st(1), st(0)
    41.     fcom
    42.     fstsw ax
    43.     sahf
    44.     jp exit             ;операнды не сравнимы
    45.     jz m12
    46.     jnc m2              ;если !z! <1, то переходим на m2
    47.     jmp m12             ;если !z! >1, то переходим на m12
    48. m3:mov p1, ecx
    49.     jmp $+7
    50. m2:mov p1, ecx
    51.     fxch
    52.     f2xm1
    53.     fadd                ;компенсируем 1
    54.     fild p1             ;показатель степенидля fscale
    55.     fld1
    56.     fscale
    57.     fxch
    58.     fincstp
    59.     fmul
    60. ;проверка на отрицательную степень
    61.     cmp flag, 1
    62.     jnz exit
    63.     fld1
    64.     fxch
    65.     fdiv
    66. exit:
    67.     mov ax, 4c00h
    68.     int 21h
    69.  
    70. main endp
    71. end main
    Вылетает ошибка
    Assembling: 1.asm
    1.asm(13) : error A2005: symbol redefinition : main
    1.asm(70) : fatal error A1010: unmatched block nesting : main


    Всё же верно! Что не так?
     
  6. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    NagarD
    main proc far наверное добавить надо.
    не суть правда но метка main не нужна.
     
  7. NagarD

    NagarD New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2011
    Сообщения:
    4
    Действительно main не нужно.

    Ошибок больше столо -

    Assembling: 1.asm
    1.asm(12) : error A2006: undefined symbol : DGROUP
    1.asm(15) : error A2074: cannot access label through segment registers
    1.asm(16) : error A2074: cannot access label through segment registers
    1.asm(21) : error A2074: cannot access label through segment registers
    1.asm(46) : error A2074: cannot access label through segment registers
    1.asm(48) : error A2074: cannot access label through segment registers
    1.asm(52) : error A2074: cannot access label through segment registers
    1.asm(59) : error A2074: cannot access label through segment registers
    1.asm(69) : warning A4023: with /coff switch, leading underscore required for start address : main


    Ошибка в 12 строке - это mov ax, @data почему?
    опять глобальная ошибка?
     
  8. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    NagarD
    А с какими ключами компилите?
     
  9. NagarD

    NagarD New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2011
    Сообщения:
    4
    таким батником

    Код (Text):
    1. ml /c /coff 1.asm
    2. Link /SUBSYSTEM:WINDOWS 1.obj
    3. pause
     
  10. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    model small под винду не канает, там только флэт.
    с другой стороны под винду запрещены прерывания, а у вас они есть.
    непонятно у вас программа под что.