Всім привіт!
Допоможіть перевести із асемблера на debug.exe
1. Нехай x, z — байти, y, v — слова. Обчислити
v=-2- ((х+2)y-1)/(z+2)
Перевірити на двох тестових даних:
1) вихідні дані: x =-3h, y =3h, z =-3h; результат: v =-6h.
2) вихідні дані: x =7Eh, y =4000h , z =-70h; результат: v =4A77H.
.model tiny ; модель пам'яті, що використовуєтьсяСОМ-програми
.code ; початок сегменту коду
.386 ; эемуляція процесора 386
org 100h ; початкове значення лічильника- 100h
start:
;обчислюємо числівник
mov al,x ; змінну x переносимо в регістр AL
cbw ; "розширюємо" на весь регістр AX (якщо число додатнє то AH заповнюється 0-ми, інакше - 1-ми)
add ax,2 ; x+2
imul y ; множимо регістр AX на змінну y
; при цьому молодші розряди результату запишуться в AX а старші в DX
; обєднуємо їх в одному регістрі EAX
push ax ; зберігаємо значення AX
mov eax,edx ; копіюємо EDX в EAX
shl eax,16 ; змістимо старші біти результату множення в старшу частину регістра EAX
pop ax ; а в молодшу відновимо молодші біти результату множення
dec eax ; зменшимо результат на 1
push eax ; зберігаємо проміжний результат
xor eax,eax ; обнулимо EAX
;обчислюємо знаменник
mov al,z ; змінну z переносимо в регістр AL
cbw ; "розширюємо" на весь регістр AX
cwde ; "розширюємо" на весь регістр EAX
add eax,2 ; z+2
mov ebx,eax ; зберігаємо знаменник в регістрі EBX
pop eax ; відновлюємо числівник
;обчислюємо сам дріб
xor edx,edx ; обнуляємо регістр залишку
bt eax,31 ; дивимся знак числівника по 1 біту
jnc p1 ; якщо 1 біт = 0, тобто числівник додатній, то приступаємо до ділення
bt ebx,31 ; дивимся знак знаменника по 1 біту
jnc p1 ; якщо 1 біт = 0, тобто знаменник додатній , то приступаємо до ділення
neg eax ; ці рядки виконуються тільки якщо і в числівнику і знаменнику відємні числа
neg ebx ; в цьому випадку поміняємо знак у них (зменшимо дріб на -1)
p1: idiv ebx ; відповідно саме ділення (результат записується в EAX залишок - в EDX)
neg eax ; міняємо знак у значення дробу
sub eax,2 ; і віднімаємо 2
call print_eax ; виводимо результат на экран
ret ; вихід
;процедура виводу на екран вмістимого регістру EAX
print_eax proc
pushad ; зберігаємо всі загальні регістри
mov cx,8 ; задаємо кількість повторювань циклу
loop1: xor dx,dx ; обнуляємо DX
xor ebx,ebx ; обнуляємо EBX
shld ebx,eax,4 ; переносимо 4 старших біта із регістру EAX в регістр EBX
sal eax,4 ; зміщуємо сам регістр EAX щоб у наступній ітерації були інші біти
mov dl,csp1[bx];заносимо в DL 16-ий символ що відповідає 4 отриманим бітам
push eax ; зберігаємо EAX
mov ah,2 ; номер функції DOS "вивід символу"
int 21h ; виклик DOS
pop eax ; відновлюємо EAX
loop loop1 ; зменшуючи регістр CX переходимо на наступну ітерацію (поки CX не стане =0)
popad ; відновлюємо всі загальні регістри
ret ; вихід з процедури
pp1 db *0123456789ABCDEF* ; рядок 16-х символів для друку
endp print_eax ; кінець процедури
x db 7Eh ; змінні
y dw 4000h ; і їх
z db -70h ; значення
end start ; кінець програми
2. Задано рядок із трьох десяткових цифр.Якщо всі вони різні, то переставити їх в зворотньому порядку, якщо ні-замінити їх на відповідні букви (‘0’-на ‘a’, 1-на ‘b’ і т.д.).
.model tiny ; модель пам'яті, що використовується для СОМ-програми
.code ; початок сегменту коду
org 100h ; початкове значення лічильника - 100h
start:
mov al,cs:s1[0] ; переміщаємо перший символ вихідного рядка в AL
mov ah,cs:s1[1] ; перемещаем другий символ вихідного рядка в AH
cmp al,ah ; порівнюємо їх
je p1 ; і якщо вони рівні то переходимо на ту частину програми
; де цифри перетворюємо на букви
mov al,cs:s1[0] ; аналогично робимо для 1 і 3 символа
mov ah,cs:s1[2]
cmp al,ah
je p1
mov al,cs:s1[1] ; и для 2 и 3
mov ah,cs:s1[2]
cmp al,ah
je p1
; в цю частину програми ми потрапляємо якщо всі три цифри
; попарно різні і тут ми переставляємо цифри в зворотньому порядку
mov al,cs:s1[0] ; зберігаємо перший символ
xchg al,cs:s1[2] ; міняємо його з третім
mov cs:s1[0],al ; на місце першого записуємо третій
jmp p2 ; переходимо на місце де цифри перетворюємо на букви
p1:
; в цю частину програми ми потрапляємо тільки якщо є хоча б одна пара однакових цифр
; і тут ми замінюємо цифри на букви
add cs:s1[0],50h ; 50h це є різниця ASCII кодів символів *0* і *А*
add cs:s1[1],50h ;*1* і *Б*, і т д.
add cs:s1[2],50h ;
p2:
; виводимо отриманий рядок на монітор
mov dx,offset s1 ; адреса початку рядка
mov ah,9 ; функція DOS друку рядка
int 21h ; виклик DOS
ret
s1 db *099*,0dh,0ah,*$* ; сам рядок
end start