Консультация № 161688
01.03.2009, 13:57
0.00 руб.
0 11 1
Здравствуйте!
Помогите мне, пожалуйста, решить два примера на Ассемблере: У=(а*а*а)-(в/2), если в>0 и У=а+(в*2), если в<=0.
У меня что-то получилось, но я не уверен в правильности. По возможности, посмотрите его, пожалуйта, если он неверен, напишите, пожалуйста, свой.
Мой код в приложении.
ОЧЕНЬ надеюсь на помощь, спасибо!

Приложение:
код первого примера:
xor ax,ax
key_2$bin
mov bl, al
cmp bl, 0
jg M1
M1:
xor ax,ax
key_2bin
mov cl,al
imul al
imul cl
mov dl,al
mov al, bl
mov bh, 2
div bh
sub dl, al
print_number

Второй решил аналогично, если что, могу код прислать.

Обсуждение

давно
Посетитель
7438
7205
02.03.2009, 12:49
общий
В каких пределах числа а и в? От этого зависит реализация...
Обратите внимание на а3, в2...
В общем случае, если а - байт, то для а3 надо 3 байта!, а если точно а<6, то можно обойтись одним байтом.
Аналогично, и с в...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
02.03.2009, 18:31
общий
А, В и С - это небольшие числа порядка 1,2,3, может быть, 10. В общем, до 50 - это точно. Это учебная программка.
давно
Старший Модератор
31795
6196
02.03.2009, 21:56
общий

503=125'000, т.е. выходит за пределы одного слова(16-ть бит), а Вы учебная программа.
Условие уточните.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
02.03.2009, 22:51
общий
Если честно, я написал условие задачи так, как оно мне было дано, больше ничего дано не было. 50, конечно, я загнул (не подумал про то, что оно в кубе) На самом деле - это очень небольшие числа порядка 1, 2, 3, 4.
давно
Посетитель
7438
7205
03.03.2009, 11:46
общий
это ответ
Здравствуйте, AkaProc!
Все таки обобщу. Будем считать, что числа такие, что а3 помещается в слово, а не в байт
Если надо, можете самостоятельно переделать на работу с байтами.
Кроме того, умножение/ деление на 2 лучше делать сдвигом на 1 бит
Ну и добавил подпрограмму вывода числа.
Удачи!

Приложение:
;У=(а*а*а)-(в/2), если в>0 и У=а+(в*2), если в<=0
.model tiny
.data
a db 4
b db 6

.code
.startup
mov al,'Y'
int 29h
mov al,'=' ;'Y='
int 29h
mov al, a
mov ah, b
call calc_y ;посчитаем
call print_number ;выведем число
mov al,0ah ;перевод на следующую строку
int 29h
mov ax, 4c00h
int 21h

calc_y proc
xor bx, bx
mov bl, ah ;bx = числу в
cmp bl, 0 ;проверим условие
jg M1 ;если в > 0, то идем на У=(а*а*а)-(в/2)
;У=а+(в*2)
sal bx, 1 ;умножим на 2 сдвигом влево на 1 бит
mov ah, 0 ;сделаем из байта слово
add ax, bx ;y=ax=а+(в*2)
jmp M2
;У=(а*а*а)-(в/2)
M1:
sar bx, 1 ;разделим на 2 сдвигом на 1 бит вправо (bx = в/2)
xor cx, cx ;сохраним а в слове cx
mov cl, al
imul al ;ax = al * al
imul cx ;dx:ax = ax * cx = al * al * al = a * a * a (считаем, что dx=0)
sub ax, bx ;y = a*a*a - в/2
M2:
ret
calc_y endp

print_number proc ;вывод числа из ax
mov bx,10 ;десятичная система
xor cx,cx ;счетчик цифр в числе

isDiv: xor dx,dx ;подготовим число - будем делить dx:ax на bx
div bx ;делим число на 10
push dx ;запоминаем в стеке остаток от деления
inc cx ;считаем количество запоминаемых символов
or ax,ax ;продолжаем пока АХ не равно 0
jnz isDiv

isOutNum: ;выводим из стека цифры в нужном порядке
pop ax
or al,30h ;переводим цифру в символ
int 29h ;выводим в режиме телетайпа
loop isOutNum;повторяем вывод в цикле
ret
print_number endp

end
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
03.03.2009, 15:13
общий
У меня есть еще вопросы, если не возражаете:
1) А если у меня 32 или 64-разрядный процессор, и я пишу название регистра "АХ", а не "ЕАХ", то как у меня тогда работает процессор? Ведь, насколько я знаю, АХ - это 16-разр регистр у 16-разр процессоров, а у 32-разр он называется ЕАХ. "Е" - означает "расширенный", т.е. у 32-разр нет регистра АХ, но есть ЕАХ. Правильно ли я мыслю? А как же тогда этот регитр называется у 64-разр процессоров?
2) А как же тогда происходит оперирование, например, с 8-байтными числами? Ведь, у 32-разр процессоров АЛУ 32-разрядное. Т.е., например, как происходит умножение 8-байтного числа на число такой же разрядности?
давно
Старший Модератор
31795
6196
03.03.2009, 15:48
общий

Не правильно!
регистр ЕАХ доступен как полностью, т.к. и почастям.
|  E   A  X |
|   |   A X |
|   |AH|AL|

примеру АХ=16*AH + AL
от того какая операция выбрана будет сгенерирован соответсвующий код
Посмотрите эту ссылку
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
7438
7205
03.03.2009, 16:55
общий
Вообще-то, этот вопрос означает начало следующего вопроса. Ну да ладно...
1) У 32-битного процессора AX означает не что иное, как младшее слово EAX. Т.е. есть и EAX, и AX.
И вообще, 32-битный процессор может оперировать следующими регистрами общего назначения:
Байт: al, bl, cl, dl, ah, bh, ch
Слово: ax, bx, cx, dx, di, si, bp, sp
Двойное слово: eax, ebx, ecx, edx, edi, esi, ebp, esp
Нетрудно догадаться, что буковка в конце у байтов означает младший (l) или старший байт (h),
если буквы нет (у слов), то регистр является младшей половиной более крупного регистра (с буквой e).
64-битный процессор имеет следующие регистры общего назначения:
Байт: al, bl, cl, dl, dil, sil, bpl, spl, r8l - r15l
Слово: ax, bx, cx, dx, di, si, bp, sp, r8w - r15w
Двойное слово: eax, ebx, ecx, edx, edi, esi, ebp, esp, r8d - r15d
Четвертное слово: rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp, r8 - r15
Видим, что появились дополнительные регистры r8 - r15
Кроме того видим, что байтами могут быть только младшие половины слов,
в остальном все аналогично.
Источник - manual от Intel, страницы 77-81
2)Умножение 8-байтного слова на 8-байтное слово на 32-битном процессоре осуществляется столбиком
при помощи небольшой подпрограммки, которую несложно и самому написать.
Удачи!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
03.03.2009, 18:54
общий
Я вам обоим очень благодарен, вы мне, прям, глаза раскрываете! У меня еще 3 маленьких вопроса: А если у меня Винда 32-битная, то я могу пользоваться регистрами RBX, RAX и тд. А для чего регистры r8 - r15 ? А если я умножаю 2
8-байтных слова столбиком, то это значит, что сначала гружу в АЛУ младшие 32 разряда, затем старшие??? Или как? По-моему больше нет способа ибо я ошибюсь.Это последние вопросы, думаю, больше не возникнет.
давно
Посетитель
7438
7205
04.03.2009, 10:39
общий
Логика подсказывает, что тут важно, не какая Windows, а какой процессор. Если он 32-битный, то, естественно пользоваться 64-битными регистрами нельзя.
Если система 32-битная на 64-битном процессоре, но, наверное, можно.
Регистры r8-r15 - это дополнительные регистры, такие же как rax,...
При умножении считаем два 32-разрядных слова двумя разрядами, например, A * 232 + B и C * 232 + D.
И умножаем, как два двузначных числа. (Вспоминаем 2 класс начальной школы ). Держите программку для беззнакового умножения, изучайте.
Код:
	.model	tiny, C
.data
x dq 1234567812345678h
y dq 1234567812345678h
z dq 2 dup (?)

.code
.386
.startup
call mult64, offset x, offset y, offset z
.exit 0

;AB * CD
mult64 proc px:word, py:word, pz:word
mov di, px
mov si, py
mov bx, pz

mov eax, [di]
mul dword ptr [si]
mov [bx], eax
mov [bx+4], edx ;B * D

mov eax, [di+4]
mul dword ptr [si]
add [bx+4], eax
adc edx, 0
mov [bx+8], edx ;A * D

mov eax, [di]
mul dword ptr [si+4]
add [bx+4], eax
adc [bx+8], edx
mov eax, 0
adc eax, 0
mov [bx+12], eax ;B * C

mov eax, [di+4]
mul dword ptr [si+4]
add [bx+8], eax
adc [bx+12], edx ;A * C

ret
mult64 endp
end
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.03.2009, 20:39
общий
Вы мне очень помогли. Большое спасибо!
Форма ответа