Помогите пожалуйста написать код на ассемблере
Найти разницу чисел 4836 и 2454. Младший байт результата поделить на 2. Поместить по адресу 30 h внутренней памяти данных младшую десятичную цифру результата, а по адресу 32 h – старшую.
Другие языки программирования и технологии
Программирование на ассемблер
P.s ты не указал конкретный ассемблер поэтому буду писать для x86
1) Найти разницу чисел.
Используем инструкцию вычитания (sub). Нельзя вычесть две константы (imm) поэтому потребуется занести одну из них в регистр. Для этого используется инструкция mov
mov AX, 4836
sub AX, 2454 ; вычитаем из AX число 2454 и результат помещаем в AX
2) Младший байт результата поделить на 2.
Можно было бы воспользоваться инструкцией деления (div), но т. к. 2 является степенью двойки (это и есть двойка) можно воспользоваться сдвигом.
Сдвиг вправо на n аналогичен делению на 2^n
В десятичной системе это тоже работает, но с 10. 123 / 10 = 12 и 123 ->(сдвиг) 1 = 012
Мы можем получить доступ к младшему байту регистра AX через регистр AL.
sar AL, 1
3) Поместить по адресу 30h младшую десятичную цифру результата ...
Получить нужно десятичную цифру поэтому будет делить на 10
Инструкция idiv имеет несколько возможных вариантов операндов. Нам подходит варинат. AX, r/m8.
Однаков в старшем байте регистра AX у нас все еще находится часть результата вычитания. Поэтому нам нужно очистить этот сташий байт.
Можно было бы просто сделать mov AH, 0, но так повелось что операция xor (исключающее или) гораздо быстрее.
xor AH, AH
Операция idiv не поддерживает деление на константу, поэтому занесем 10 в регистр.
mov BX, 10
Теперь делим
idiv BL
Результат будет в AL а остаток в AH
Нам нужно переместить из AH в память по адресу. Значит нужно в регистр засунуть этот адрес.
mov DX, 30h
И уже потом записать результат по адресу
mov [DX], AH
Также нужно проверить AL. Вдруг в числе была всего одна цифра. Тогда не нужно выполнять цикл и можно сразу перейти к записи результата.
Далее нам надо продолжать делить пока не получим самую старшую цифру. Для этого используем цикл.
@loop
xor AH, AH
idiv BL
test AL, AL
jnz @loop
Аналогично записываем разультат.
mov DX, 32h
mov [DX], AH
Итого получается такой код:
mov AX, 4836
sub AX, 2454
sar AL, 1
xor AH, AH
mov BX, 10
div BL
mov DX, 30h
mov [DX], AH
test AL, AL
jz @afterLoop
@loop:
xor AH, AH
div BL
test AL, AL
jnz @loop
@afterLoop:
mov DX, 32h
mov [DX], AH
1) Найти разницу чисел.
Используем инструкцию вычитания (sub). Нельзя вычесть две константы (imm) поэтому потребуется занести одну из них в регистр. Для этого используется инструкция mov
mov AX, 4836
sub AX, 2454 ; вычитаем из AX число 2454 и результат помещаем в AX
2) Младший байт результата поделить на 2.
Можно было бы воспользоваться инструкцией деления (div), но т. к. 2 является степенью двойки (это и есть двойка) можно воспользоваться сдвигом.
Сдвиг вправо на n аналогичен делению на 2^n
В десятичной системе это тоже работает, но с 10. 123 / 10 = 12 и 123 ->(сдвиг) 1 = 012
Мы можем получить доступ к младшему байту регистра AX через регистр AL.
sar AL, 1
3) Поместить по адресу 30h младшую десятичную цифру результата ...
Получить нужно десятичную цифру поэтому будет делить на 10
Инструкция idiv имеет несколько возможных вариантов операндов. Нам подходит варинат. AX, r/m8.
Однаков в старшем байте регистра AX у нас все еще находится часть результата вычитания. Поэтому нам нужно очистить этот сташий байт.
Можно было бы просто сделать mov AH, 0, но так повелось что операция xor (исключающее или) гораздо быстрее.
xor AH, AH
Операция idiv не поддерживает деление на константу, поэтому занесем 10 в регистр.
mov BX, 10
Теперь делим
idiv BL
Результат будет в AL а остаток в AH
Нам нужно переместить из AH в память по адресу. Значит нужно в регистр засунуть этот адрес.
mov DX, 30h
И уже потом записать результат по адресу
mov [DX], AH
Также нужно проверить AL. Вдруг в числе была всего одна цифра. Тогда не нужно выполнять цикл и можно сразу перейти к записи результата.
Далее нам надо продолжать делить пока не получим самую старшую цифру. Для этого используем цикл.
@loop
xor AH, AH
idiv BL
test AL, AL
jnz @loop
Аналогично записываем разультат.
mov DX, 32h
mov [DX], AH
Итого получается такой код:
mov AX, 4836
sub AX, 2454
sar AL, 1
xor AH, AH
mov BX, 10
div BL
mov DX, 30h
mov [DX], AH
test AL, AL
jz @afterLoop
@loop:
xor AH, AH
div BL
test AL, AL
jnz @loop
@afterLoop:
mov DX, 32h
mov [DX], AH
Дилшод Матякубов
Я тут учитываю, что результат вычитания положительный. Если же нужно читывать и другой вариант (что результат может оказаться отрицательным), то div нужно заменить на idiv и "xor AH, AH" на "CBW"
На асме вместо деления на 2 используй операцию побитового сдвига.
Alexei Furs
я не знаю как выделить младший байт результата, что бы было что делить
Сергей Хитрин
mov bx 2454
mov ax 4836
sub ax bx// если не изменяет память в ax результат
xchg al ah//меняем байты
слушай проверь толи тебе надо
mov ax 4836
sub ax bx// если не изменяет память в ax результат
xchg al ah//меняем байты
слушай проверь толи тебе надо
Alexei Furs
да уже много про сдвиги читал, и сдвигали на 8 байтов в право, но не понятно как достать полученные значения из флага CF куда оно и отбрасывает всё что вылезает за сетку
Сергей Хитрин
вопрос не в теу.. а где это учат.. зачем
Сергей Хитрин
во блин.. то что надо
подпишусь ()
Alexei Furs
что?
Похожие вопросы
- Программирование на Ассемблере
- программирование на ассемблере. Возможно ли без употребления тяжёлых наркотиков?
- Здравствуйте помогите в программирование на ассемблере. Нужно зеркально отобразить массив из 256 байт
- Вопрос по изучению языка Ассемблера под MS DOS. (Нужны советы по программному обеспечению/программированию)
- Ассемблер и программирование.
- Почему здесь нет языка программирования ассемблер?
- нужны ли ассемблер и C/C++ в современном программировании ?
- Ассемблер. В чем главная фишка ассемблера? Почему его так часто упоминают в книгах по программированию.
- Почему в наше время не изучают ассемблер? Ведь это и есть настоящее могущество в программировании, не?
- Что может ассемблер?