0 / 0 / 0
Регистрация: 23.11.2009
Сообщений: 3
1

(MCS-51) Деление на 2 шестнадцатеричного числа со знаком

23.11.2009, 01:20. Показов 5513. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Дорого уважаемые программисты,
возникла такая вот задачка,

Необходимо составить программу деления на 2 шестнадцатиричного(двухбайтного) числа со знаком. Входные данные - числа, допустим лежат в 2х регистрах. При этом само число может быть как положительное, так и отрицательное. Результат записать в эти же регистры.
Я знаю что необходимо учитывать команду логического сдвига с использованием бита переноса.
Т.е. для положительного вроде бы нужно сделать логический сдвиг влево для каждого байта с учетом бита перенос. Как это оформить на tasme?
Но это для положительного числа, а как быть с отрицательными? Если можно, с исходным кодом.

Обыскал гугл и яндекс, к сожалению, ничего не нашел,
Спасибо. Последняя надежда на вас!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.11.2009, 01:20
Ответы с готовыми решениями:

Укажите десятичный эквивалент шестнадцатеричного числа BF, если это число со знаком
2) Укажите десятичный эквивалент шестнадцатеричного числа BF, если это число со знаком Мне не...

Деление двухбайтового числа на однобайтовое MCS-51
Доброго времени суток! В процессе написания программы на ассемблере для микроконтроллера MCS-51...

Деление числа со знаком
Здравствуйте, совсем недавно начал интересоваться ассемблером, подскажите почему у меня при делении...

[MCS-51 AT89C51] Деление многобайтных чисел
Деление многобайтних чисел (деленное N = 2, делитель N = 1), которые задаются в виде двух векторов...

Деление со знаком
Нужно разделить две переменные размером в слово, и поместить результат в переменную у. как это...

6
2537 / 833 / 10
Регистрация: 31.05.2009
Сообщений: 1,668
23.11.2009, 01:34 2
Команда sar ?
Assembler
1
2
sar eax,1 ; разделить eax на 2 с учетом знака
sar ebx,1 ; разделить ebx на 2 с учетом знака
1
64 / 63 / 3
Регистрация: 16.11.2009
Сообщений: 156
23.11.2009, 01:36 3
sar - арифметический сдвиг вправо. Применяется для знакового деления на степени двойки. То-есть старший бит копируется в себя и вправо. Округление в стороную отрицательной бесконечности.

P.S. эх... Опередили.
1
0 / 0 / 0
Регистрация: 23.11.2009
Сообщений: 3
23.11.2009, 02:01  [ТС] 4
Спасибо большое за ответ на тасм, но тут сразу 2 вопроса.
1. Нашел статью где написано, что при арифметическом делении, когда мы
В конце концов дойдем до числа -1, и сколько его не сдвигай результат
всегда будет один и тот же, хотя если прямо разделить -1 на 2 результат будет равен 0, -5 деленное на 8 тоже будет равен нулю (модуль числителя меньше знаменателя). Тогда и получается, что замена деления числа СО ЗНАКОМ операциями сдвига вправо в общем случае НЕКОРРЕКТНА.
что вы думаете по этому поводу?
2. условие моей задачи задано под древний микроконтроллер MCS-51, поэтому регистры там входные R5 и R4-старший и младший байты соответственно и насколько я понимаю операция деления вся выглядит вот так, с учетом того что сдвиг там можно делать только в аккумуляторе.

Assembler
1
2
3
4
5
6
7
CLR C   ;сброс бита С
MOV A,R5
RRC A ;Логический сдвиг вправо старшего байта
MOV R5,A
MOV A,R4
RRC A ;Логический сдвиг вправо младшего байта
MOV R4,A
Это для положительного. Правильно ли я написал?
А как быть для отрицательного, если насколько я понял операции арифметического сдвига там нет в природе, поэтому необходимо реализововать инвертирование (получить обратный код), потом прибавить единицу и уже потом готовое положительное прогнать по указанной выше?
Если можно ваши мысли и код.

П.С. За команду на тасме спасибо, я заодно и там хочу эту прогу настрепать. для личного успокоения.
Спасибо, жду ваших ответов.
0
64 / 63 / 3
Регистрация: 16.11.2009
Сообщений: 156
23.11.2009, 03:13 5
Цитата Сообщение от LuckyMan777 Посмотреть сообщение
1. Нашел статью где написано, что при арифметическом делении, когда мы
В конце концов дойдем до числа -1, и сколько его не сдвигай результат
всегда будет один и тот же, хотя если прямо разделить -1 на 2 результат будет равен 0, -5 деленное на 8 тоже будет равен нулю (модуль числителя меньше знаменателя). Тогда и получается, что замена деления числа СО ЗНАКОМ операциями сдвига вправо в общем случае НЕКОРРЕКТНА.
что вы думаете по этому поводу?
IDIV округляет в сторону нуля, поэтому -1/2=0. SAR округляет в сторону минус бесконечности, поэтому -1/2=-1. -5/8=-1 по SAR, -5/8=0 по IDIV.
При изображении знаковых числел с помощь дополнения до двух, 0 - позитивное число, а -0 не существует. SAR копирует знаковый байт, значит 1000b, после трех SAR становится 1111b, что равно -1, и при последующем вращении всегда останется -1. Помоему логично и корректно. Если надо иметь 0 при делении, достаточно проверить на -1 и превратить в 0. Если бы логика была дополнение до одного, тогда бы был -0, но тут свои тараканы.


MCS-51 я не знаю. Но согласен с вариантом. Инвертировать, прибавить, сдвинуть, обратно инвертировать, прибавить.
0
0 / 0 / 0
Регистрация: 23.11.2009
Сообщений: 3
24.11.2009, 14:19  [ТС] 6
В общем, проблема решена вот таким вот незамысловатым способом: двойное инвертирование,+1 .Прилагаю решение Для МК семейства 8051. Может кому-то поможет в будующем.

Assembler
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
org 00h        
jmp start
org 30h
start:
mov R5,#00000000b
mov R4,#00001000b
 
MOV A,R5               ;proverka na otricatelnost
CJNE A, #0, otricat      
jmp polozhit
 
dop_kod:
MOV A,R5  ;ivertirovanie
CPL A
MOV R5,A
MOV A,R4
CPL A
MOV R4,A
 
ADD A,#1h ;+1
MOV R4,A
MOV A,R5
ADDC A,#0H
MOV R5,A
ret
 
otricat:
LCALL dop_kod
 
CLR C     ;logicheskiy sdvig
MOV A,R5
RRC A
MOV R5,A
 
MOV A,R4
RRC A
MOV R4,A
 
LCALL dop_kod
jmp konec ;perehod na konec programmi
 
polozhit: ;procedyra dlya polozhitelnih chisel
CLR C
MOV A,R5  ;logicheskiy sdvig
RRC A
MOV R5,A
MOV A,R4
RRC A
MOV R4,A
konec:
end
0
Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
24.11.2009, 15:01 7
Простым сдвигом знаковое число не делится (это будет правильно работать только для положительных чисел). Вот что делает gcc для sparc:

C
1
2
3
4
5
6
int i;
 
void func (void)
{
  i = i / 2;
}
Код
Исходное значение в регистре %o5

srl     %o5, 31, %o4   ; o4 = o5 >> 31 - логический сдвиг вправо
add     %o5, %o4, %o5  ; o5 = o5 + o4;
sra     %o5, 1, %o5    ; o5 = o5 >> 1 - арифметический (знаковый) сдвиг вправо
Поскольку у тебя значение 16-битное, то вместо 31 надо использовать 15. Математику написал, ну а на интеловскую систему команд сам переведи

Добавлено через 1 минуту
Т.е. смысл этого действия такой, что для отрицательных значений перед сдвигом надо сначала прибавить единицу
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.11.2009, 15:01
Помогаю со студенческими работами здесь

Деление/умножение со знаком
Задача: используя 16-битные значения трёх переменных, вычислить k по формуле k=(a*b)/(а+c) То,...

Ассемблерная вставка. Деление со знаком
На консоль выводит непонятно что - 8.40779e-045 float res; _asm{ mov eax, 20; mov ebx,...

Вывод шестнадцатеричного числа
Нужно вывести шестнадцатеричное число. Где то закралась ошибка, заданное число выводит в виде 1133,...

Запись шестнадцатеричного числа
Здравствуйте. нужна помощь. понадобилось шестнадцатеричное представление числа, погуглил не нашел,...

Сложение десятичного и шестнадцатеричного числа
Привет. Есть проблемка. Не правильно складываются 2 числа в разных СС. А именно число K и &V1....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru