Программирование разветвляющихся алгоритмов ассемблер

Программирование разветвляющихся алгоритмов ассемблер

Доброго времени суток!
Помогите объединить 2 куска кода в один. В первом реализовано ввод целого числа, его проверку на корректный ввод, и вывод на экран. А второй — это код решающий систему уравнений из вложений. Как мне объединить эти два кода в один? Чтобы в зависимости от введенного «Х» решалось соответственное уравнение.
1-й кусок кода:

 STSEG SEGMENT PARA STACK "STACK" DB 64 DUP(00h) STSEG ENDS DSEG SEGMENT PARA PUBLIC "DATA" OUT_MESS db 'Enter an integer number (from -9999 to 9999): ', '$' ERROR DB 10,"Wrong input, you should enter an integer number from -9999 to 9999. ",10,13,'$' OUT_MES DB 10,"Your entered number = ",'$' REP_MES DB 10,13,"If you want to repeat, press 'y' or any key. ",10,13,'$' IN_NUMB DB 6,'*',6 DUP('?') SHIFT DB 0 TEN DW 1 NUMBER DW 00h DSEG ENDS CSEG SEGMENT PARA PUBLIC "CODE" MAIN PROC FAR ASSUME SS:STSEG, CS:CSEG, DS:DSEG PUSH DS XOR AX,AX PUSH AX MOV AX,DSEG MOV DS,AX START: MOV AL,6 MOV IN_NUMB,AL LEA DX,OUT_MESS MOV AH,09H INT 21H LEA DX,IN_NUMB MOV AH,0AH INT 21H CALL P_STR CMP CX,00h ;this JE ERR_IN LEA DX,OUT_MES MOV AH,09H INT 21H CALL OUT_STR ERR_IN: MOV AL,2 MOV IN_NUMB,AL LEA DX,REP_MES MOV AH,09h INT 21h LEA DX,IN_NUMB MOV AH,0AH INT 21H CMP IN_NUMB+2,'Y' JE START CMP IN_NUMB+2,'y' JE START RET MAIN ENDP P_STR PROC NEAR LEA BX,IN_NUMB MOV AL,'-' CMP AL,IN_NUMB+2 JE RI_ZN MOV AL,'+' CMP AL,IN_NUMB+2 JE RI_ZN MOV AL,30h CMP AL,IN_NUMB+2 JE RInp MOV AL,00h CMP AL,[IN_NUMB+1] JE INC_INP MOV DL,05H CMP IN_NUMB+1,DL JB RInp JMP NO_ST RInp: MOV AL,02h MOV SHIFT,AL JMP GO_1_SYM RI_ZN: MOV AL,03h MOV SHIFT,AL MOV AL,-1h ADD IN_NUMB+1,AL GO_1_SYM: XOR CX,CX XOR DX,DX XOR AX,AX MOV AL,SHIFT ADD BX,AX MOV AL,[BX] CYCLE: ADD AL,-30H JS INC_INP CMP AL,09h JG INC_INP PUSH AX INC BX MOV AL,[BX] CMP AL,0Dh JNE CYCLE XOR AX,AX INC AX MOV CL,IN_NUMB+1 MOV NUMBER,DX TO_NUMB: MOV TEN,AX POP BX MUL BX ADD NUMBER,AX MOV AX,10 MUL TEN LOOP TO_NUMB MOV CX,01h MOV DL,IN_NUMB+2 CMP DL,'-' JNE P_END MOV AX, NUMBER NEG AX MOV NUMBER, AX P_END: RET INC_INP: XOR DX,DX LEA AX,IN_NUMB MOV DL,SHIFT SUB BX,DX SUB BX,AX JZ NO_ST MOV CX,BX IS_ST: POP BX LOOP IS_ST NO_ST: LEA DX,ERROR MOV AH,09H INT 21H MOV CX,00h RET P_STR ENDP OUT_STR PROC NEAR MOV AX,NUMBER CMP AX,00h JGE DOD NEG AX MOV NUMBER,AX MOV AH,02h MOV DX,'-' INT 21h DOD: XOR DX,DX XOR CX,CX MOV BX,0Ah MOV AX,NUMBER OUT_SYM: IDIV BX ADD DX,30h PUSH DX INC CX XOR DX,DX CMP AX,00h JNE OUT_SYM MOV AH,02h OUT_S: POP DX INT 21h LOOP OUT_S RET OUT_STR ENDP CSEG ENDS END MAIN
mov eax,x cmp eax,-1 jl v1 jg v2 xor eax,eax jmp v3 v1: dec eax jmp v3 v2: lea ecx,[eax*2+1] mov eax,x sal eax,1 imul eax mov ebx,eax mov eax,x imul x imul x add eax,ebx add eax,11 cdq idiv ecx v3: mov z,eax

Источник

Читайте также:  Экономические приложения задачи динамического программирования

Программирование разветвляющихся алгоритмов ассемблер

Условные конструкции позволяют направить действие программы по одному из путей в зависимости от определенного условия. В языке ассемблера нет подобных конструкций в отличие от языков высокого уровня. Однако, используя сравнение значения флагов, метки и переходы, мы можем сами определить подобные конструкции.

Имитация конструкции if..else

Во многих распространеных языках высокого уровня есть конструкция if..else, которая в зависимости от условия выполняет те или иные действия. С помощью бейсикоподобного синтаксиса обобщенно эту конструкцию можно представить следующим образом:

IF условие THEN выполняемые действия, если условие верно ELSE выполняемые действия, если условие НЕ верно END IF

Что касается ассемблера, то тут придется написать гораздо больше инструкций, чтобы построить логику, но в общем случае это выглядит примерно так:

CMP Xn, Operand2 B.NE else действия, если значения равны B endif else: действия, если значения НЕ равны endif:

Сначала инструкция CMP сравнивает значение некоторого регистра Xn с Operand2. Далее проверяем неравество B.NE else , и если значения НЕ равны, переходим на метку else . Если значения равны, то просто выполняются последующие инструкции ДО метки else .

В данном случае применяется операция NE , которая проверяет, сброшен ли Z-флаг (что эквивалентно тому, что два значения не равны). Но естественно это может быть и другая операция сравнения.

После метки else идут инструкции, которые выполняются, если значения из инструкции CMP не равны.

Завершается все меткой endif , после которой идут инструкции остальной части программы.

Посмотрим на примитивном примере — сравним значение регистра с числом, и в зависимости от результата сравнения установим определенный код возврата — 1 (если значения равны) и 2 (если значения не равны):

// METANIT.COM. Пример программы с условной конструкцией, // которая сравнивает два значения .global _start _start: MOV X1, #5 // помещаем в X1 число 5 CMP X1, #6 // сравниваем значение из X1 с числом 6 B.NE _else // если равенство X1 == 5 не верно, переход к метке _else MOV X0, #1 // помещаем в регистр X0 в качестве кода возврата число 1 (значения равны) B _endif // переход к метке _endif для завершения условной конструкции _else: MOV X0, #2 // помещаем в регистр X0 в качестве кода возврата число 2 (значения НЕ равны) _endif: // завершение условной конструкции //выходим из программы MOV X8, #93 // номер функции Linux для выхода из программы - 93 SVC 0 // вызываем функцию и выходим из программы

Здесь помещаем в регистр X1 число 5, а затем с помощью инструкции CMP сравниваем его с число 6. Очевидно, что у нас значения не равны, поэтому инструкция B.NE увидит, что Z-флаг сброшен, и выполнит переход на метку _else , где в регистр X0 в качестве кода возврата из программы будет помещено число 2.

Затем выполняется переход к метке _endif , которая знаменуют окончание условной конструкции и за которой идут по сути остальные инструкции программы (в данном случае вызов функции выхода из программы)

Если бы значения были бы равны, то в регистр X0 было бы помещено число 1, а затем произошел переход к метке _endif .

Имитация конструкции switch..case

В ряде языков высокого уровня есть конструкция switch..case , которая последовательно сравнивает некоторое выражение с набором значений:

Общий алгоритм данной конструкции может быть следующим:

  1. С помощью CMP сравниваем значение регистра с некоторым значением.
  2. Если сравнение оказалось НЕ верным, то переходим к следующей метке, которая сравнивает значение регистра с новым значением. Если сравнение оказалось верным, то выполняем определенные действия и затем переходим к метке завершения конструкции.
  3. Если ни одно из сравнений в инструкциях CMP НЕ является верным, выполняем действия по умолчанию.

Например, определим следующую программу:

// METANIT.COM. Пример программы с условной конструкцией аля switch..case .global _start _start: MOV X1, #2 // помещаем в X1 сравниваемое значение - число 2 _case_1: CMP X1, #1 // сравниваем значение из X1 с первым значением - числом 1 B.NE _case_2 // если равенство X1 == 1 НЕ верно, переход к метке _case_2 MOV X0, #1 // помещаем в регистр X0 в качестве кода возврата число 1 B _endswitch // переход в конец конструкции _case_2: CMP X1, #2 // сравниваем значение из X1 с первым значением - числом 2 B.NE _case_3 // если равенство X1 == 2 НЕ верно, переход к метке _case_3 MOV X0, #2 // помещаем в регистр X0 в качестве кода возврата число 2 B _endswitch // переход в конец конструкции _case_3: CMP X1, #3 // сравниваем значение из X1 с первым значением - числом 3 B.NE _default // если равенство X1 == 3 НЕ верно, переход к метке _default MOV X0, #3 // помещаем в регистр X0 в качестве кода возврата число 3 B _endswitch // переход в конец конструкции _default: MOV X0, #10 // если предыдущие сравнения НЕ верны, помещаем в регистр X0 число 10 (значение по умолчанию) _endswitch: //выходим из программы MOV X8, #93 // номер функции Linux для выхода из программы - 93 SVC 0 // вызываем функцию и выходим из программы

Здесь в регистр X1 помещается сравниваемое значение — число 2. Далее идет набор меток _case_1/_case_2/_case_3, после которых инструкция CMP сравнивает значение регистра с некоторыми значениями. Если равенство значений не верно, то переходим к следующей метке. Если равенство сравнений верно, то помещаем в регистр X0 соответствующий код возврата из программы и переходим к метке _endswitch

В данном случае, поскольку в регистре X1 находится число 2, то в регистр X0 будет помещено число 2.

Бонус

Программа с выводом текстовых сообщений в зависимости от результата сравнения:

// METANIT.COM. Пример программы с условной конструкцией, // которая сравнивает два значения .global _start _start: MOV X0, #1 // 1 = StdOut - поток вывода MOV X1, #5 // помещаем в X1 число 5 CMP X1, #6 // сравниваем значение из X1 с числом 6 B.NE _else // если равенство X1 == 5 не верно, переход к метке _else LDR X1, =equal // строка для вывода, если числа РАВНЫ MOV X2, #26 // длина строки B _endif // переход к метке _endif для завершения условной конструкции _else: // если значения не равны LDR X1, =notequal // строка для вывода, если числа НЕ РАВНЫ MOV X2, #32 // длина строки _endif: // вывод сообщения на консоль MOV X8, #64 // устанавливаем функцию Linux для вывода строки SVC 0 // вызываем функцию MOV X0, #0 // код возврата из функции - 0 MOV X8, #93 // номер функции Linux для выхода из программы - 93 SVC 0 // вызываем функцию и выходим из программы .data equal: .ascii "данные равны\n" notequal: .ascii "данные НЕ равны\n"

Источник

Разветвляющиеся алгоритмы. Ассемблер

Даны два целых числа a и b. Определить значение переменной y: если a

Циклические и разветвляющиеся программы
помогите найти наименьшее по абсолютной величине числа. Массив байт

Разветвляющиеся алгоритмы
Добрый день! Помогите, пожалуйста, новичку написать программу. Никак не могу понять, как составить.

Разветвляющиеся алгоритмы
На оси ОХ расположены три точки: a,b,c.Определить,какая из точек,b или c,расположена ближе к a.

Эксперт по электронике

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
_STACK segment para stack db 1024 dup(?) _STACK ends _DATA segment _A dw 10 _B dw 17 _Y dw ? CrLf db 0Dh, 0Ah, '$' _DATA ends _TEXT segment assume cs:_TEXT, ds:_DATA, ss:_STACK main proc ;инициализация сегментного регистра данных mov ax, _DATA mov ds, ax mov ax, [_A] cmp ax, [_B] jl @@Lesser sub ax, [_B] jmp @@Result @@Lesser: add ax, [_B] @@Result: mov [_Y], ax ;завершение программы mov ax, 4C00h int 21h main endp _TEXT ends end main

Источник

Программа ветвящейся структуры

Нужна программа на ассемблере, вычисляющая значение У, при подстановке соответсвующих значений вместо А и В.

Командные файлы ветвящейся структуры
Помогите Создать командный файл в каталоге pr8 под именем k7. Bat который проверяет наличие.

Тема: «Алгоритмы и программы ветвящейся структуры».
Даны действительные числа a, b, c, (a > 0). Полностью исследовать биквадратное уравнение ax4 + bx2.

Динамические структуры данных. Программа ввода в структуры и вывода информации из неё.
Автоматизированная информационная система на железнодорожном вокзале содержит сведения об.

Динамические структуры данных, списковые структуры (надо разобраться что делает программа)
дана программа, надо помочь выяснить что в ней делает каждая подпрограмма unit Unit6; .

ЦитатаСообщение от skaa Посмотреть сообщение

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
org 100h start: jmp begin data: A db 5 B db 3 Y db 0 begin: mov al,byte [B] cmp byte [A],al jne mne ; A=B ; 3*B mov ax,0 mov al,byte [B] mov bx,3 mul bx mov dx,ax ; -A mov ax,0 mov al,byte [A] sub dx,ax mov [Y],dl jmp mex mne: mov al,byte [B] cmp byte [A],al jg mg ; A mov al,byte [B] or al,byte [A] mov [Y],al jmp mex mg: ; A>B ; 2*A mov ax,0 mov al,byte [A] mov bx,2 mul bx mov dx,ax ; -B mov ax,0 mov al,byte [B] sub dx,ax mov [Y],dl mex: mov ah,4ch int 21h

Источник

Оцените статью