LINUX.ORG.RU
ФорумTalks

Assembler на кр580 (i8080)


0

0

в нашем любимом вузе есть чудо предмет "микропроцессорная техника", а пишут там на ассемблере под кр580, пришлось писать, теперь нада проверить, ток теперь нада проверить. Эмулятора этого чуда под linux я не нашел, поэтому юзал эмулятор спектрума на котором аналогичный процессор, но что-то мы не договорились. Помогите пожалуйста, вот программа:
Адрес Код Команда Операторы Комментарий
;Программа y=2X1+X2-X3
ORG 820 ;Начать программу с адреса 0820H
820 21 LXI H,86F ;заслать адрес ячейки памяти в регистровую пару HL
821 6F
822 08
823 3E MVI A,E0 ;заслать X1 в регистр A
824 E0
825 0E MVI C,6E ;заслать X2 в регистр C
826 6E
827 16 MVI D,60 ;заслать X3 в регистр D
828 60
829 87 ADD A ;сложить содержимое акамулятора с самим собой
82A 81 ADD C ;сложить содержимое акамулятора с регистром С
82B 92 SUB D ;вычесть содержимое регистра D из акамулятора
82C 77 MOV M,A ;заслать содержиоме акамулятора в ячейку памяти адрес которой находится в регистровой паре
END ;конец программы


ахфигеть
в начале 90-х был такой отечественный комп - назывался криста
у него была оболочка для написания програм на ассемблере кр580 , которая была даже поприличнее , чем гребаный интерпретатор бейсика ,который загружался так же , с кассеты
на этом ассемблере я умудрялся писать интерактивные игрушки в текстовом режиме
в проге вроде все верно , вот только за последнюю команду я не совсем уверен - давно это было

kto_tama ★★★★★
()
Ответ на: комментарий от kto_tama

Помоги пожалуста проверить на эмуляторе. я ее вбил в эмулятор но что-то у нас с ним не срослось. эмулятор(fuse) отказалась размещять программу по нужному адресу, а результат вычислений я вообще не нашел. Заранее благодарен!

Frolic
() автор топика

Да вроде все правильно. Я сам плохо помню, но программа вроде простая и выглядит похоже. Единственное, что не уточнены границы входных и выходных данных. Ведь результат может в один байт и не умещаться. имей это в виду. С этой точки зрения, твоя программа неправильная. Чтобы она стала правильной, надо еще учесть бит переноса и сложить его со старшим байтом ответа.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Приколись. Если не впадло, помоги учесть помоги бит переноса. А то я не совсем понимаю что это, а сдать желательно уже сегодня. Дякую!

Frolic
() автор топика

> Эмулятора этого чуда под linux я не нашел, поэтому юзал эмулятор спектрума на котором аналогичный процессор ...

Вот - посмотри, что я нашел:
http://lubyagin.discrete.ru/outgoing/for_frolic.tgz (620 kBytes)
MAC8080 - collection of macros to assemble 8080 assembler code with the TASM Turbo Assembler on a PC
Z80 - Программа эмулятора процессора Zilog Z80
asm80 - Z-80 cross assembler for Unix
cp_emu - CP/U - Control Program for Unix-like systems
dis88 - symbolic disassembler for the Intel 8088 CPU
disasm80 - 8048/8049 Disassembler in 'C'
dz80 - Z80 dissasembler that generates code that can be assembled with the Zilog public domain assembler zasm
i4004em - Intel 4004 Emulator
ma - Ma-80 v2.0Demo alpha Z80 Macro Assembler
sim8051 - A simulator for the 8051 microcontroller family
spectemu - 48k ZX-Spectrum emulator for Linux and other UNIX operating systems, with full Z80 instruction set ...

pacify ★★★★★
()
Ответ на: комментарий от pacify

Так в спектруме использовался процессор Z80, который является слизаным i8080, а кр580 в тоже является копией i8080. Походу я просто както неправильно ввожу программу. Кстати а ее нада както запускать наверное?

Frolic
() автор топика
Ответ на: комментарий от Frolic

Не, Виталий Дмитриевич. За других учиться я не хочу. Я перевыполнил план по двойной учебе (девушку тащил). Тут тебе работы по изучению на полчасика. Бит заема/переноса. Смотри регистр состояния (или флагов), кажется. Не помню, как он там звался. Когда складываешь два числа двоичных, а результат не вмещается в сетку (0xfe + 0x20, например), то в аккумуляторе останется только младший байт, т. е. 0x1e, а в регистре состояния (или флагов) выставится битик C в 1. Насколько я помню смутно, чтобы сложить с учетом бита переноса, есть команда ADC. Вот и складываешь с ним старший байт результата (результат двухбайтный должен быть). Если вычитаешь из меньшего числа большее, то тогда этот битик C имеет статус заема.

Zubok ★★★★★
()
Ответ на: комментарий от Frolic

Да, Виталий Дмитриевич. Память не подвела. Это команды ADC и SBB

ADC A <- A + (r) + Carry (C) SBB A <- A - (r) - Carry (C)

Подумай, что будет, что будет, елси ты посчитаешь по своей программе 2*132 - 1 = 263. Твоя программа посчитает 7.

Zubok ★★★★★
()
Ответ на: комментарий от Frolic

Если пользуешься эмулятором Z80, то она может в нем по-другому называться (ADC/SBC вместо ADC/SBB). В любом случае, эти команда должны быть. И складывать, и вычитать надо именно из двухбайтного результата и именно с учетом переноса.

Есть таблица соответсвий мнемоник:

http://nemesis.lonestar.org/computers/tandy/software/apps/m4/qd/opcodes.txt

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Команды то есть, просто про них нехера не написано в институтской методе!
вроде так:
Адрес Код Команда Операторы Комментарий
;Программа y=2X1+X2-X3
ORG 820 ;Начать программу с адреса 0820H
820 21 LXI H,86F ;заслать адрес ячейки памяти в регистровую пару HL
821 6F
822 08
823 3E MVI A,E0 ;заслать X1 в регистр A
824 E0
825 0E MVI C,6E ;заслать X2 в регистр C
826 6E
827 16 MVI D,60 ;заслать X3 в регистр D
828 60
829 87 ADD A ;сложить содержимое акамулятора с самим собой
82A 89 ADC C ;сложить содержимое акамулятора с регистром С
82B 9A SBB D ;вычесть содержимое регистра D из акамулятора
82C 77 MOV M,A ;заслать содержиоме акамулятора в ячейку памяти адрес которой находится в регистровой паре
END ;конец программы

Frolic
() автор топика
Ответ на: комментарий от Frolic

Мои сочувствия, но неправильно. Совсем. ADC C надо складывать уже со старшим байтом результата, а ты опять с аккумулятором складываешь. И содержимое аккумулятора с самим собой тоже надо с переносом складывать (148+148=296 -> в младшем байте 28h, в старшем 01h после его сложения с Carry). Короче, читай дальше. На методу забей. Все есть в интернете. :)

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

>ADC C надо складывать уже со старшим байтом результата, а ты опять с аккумулятором складываешь.

То есть, тьфу. Сначала с младшим байтом (это можно и ADD C использовать), сохранить аккумулятор в памяти, где младший байт, а потом после сложения с младшим батом, получить сожержимое старшего байта и сложить с ним бит переноса. А потом опять получить младший из памяти и дальше также складывать и вычитать. Обращаться к ячекам памяти можно опосредовано через (HL). Увеличиваешь на 1содержимое пары -- старший байт, уменьшаешь на один содержимое пары -- младший байт. Насколько я помню, команды сложения и вычитания работают с (HL) как с операндом вместо регистров.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Чет я недогоняю команда ADC C эт сложить содержимое акамулятора с регистром С, и или с каким то другим. Почему нельзя просто добавлять содержимое регистров с содержимым акамулятора, как я это сделал?

Frolic
() автор топика
Ответ на: комментарий от Zubok

эт типа после каждого действия результат заносить в регистр с учетом бита переноса?

Frolic
() автор топика
Ответ на: комментарий от Zubok

а че значит ADI d8 где d8 - байт непосредственных данных.?

Frolic
() автор топика
Ответ на: комментарий от Frolic

Вот так можно. писал быстро и не проверяя.

LXI H,86F ; загружаем HL адресом
MVI A,E0 ; X1 -> A
MVI C,6E ; X2 -> C
MVI D,60 ; X3 -> D
MVI E,0 ; тут будет старший байт результата = 0 пока.

ADD A ; A <- A + A
JNC L1 ; был перенос?
INR C ; Да: старший байт увеличиваем

L1: ADD C ; A <- A + C
JNC L2 ; был перенос?
INR C; Да: старший байт увеличиваем

L2: SUB D ; A <- A - D
JNC L3 ; был заем?
DCR C ; Да: уменьшаем C

Теперь в A -- младший байт, а в C -- старший. Запиши их в память.

Zubok ★★★★★
()
Ответ на: комментарий от Frolic

>Чет я недогоняю команда ADC C эт сложить содержимое акамулятора с регистром С, и или с каким то другим. Почему нельзя просто добавлять содержимое регистров с содержимым акамулятора, как я это сделал?

Что-то другое -- это бит переноса Carry. Ппц. Ты числа складывал столбиком когда-нибудь? :)) ("занимаем" и "переносим " помнишь? :) Гыыы. Поколение.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Ой, опечатался! Во всех командах DCR и INR не C, а E! INR E, DCR E

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Вот так окончательно с исправлениеями опечаток

LXI H,86F ; загружаем HL адресом
MVI A,E0 ; X1 -> A
MVI C,6E ; X2 -> C
MVI D,60 ; X3 -> D
MVI E,0 ; тут будет старший байт результата = 0 пока.

ADD A ; A <- A + A
JNC L1 ; был перенос?
INR E ; Да: старший байт увеличиваем

L1: ADD C ; A <- A + C
JNC L2 ; был перенос?
INR E; Да: старший байт увеличиваем

L2: SUB D ; A <- A - D
JNC L3 ; был заем?
DCR E ; Да: уменьшаем старший байт

L3: MOV M,A ; запоминаем младший байт
INX H ; увеличиваем HL
MOV M,E ; запоминаем старший байт

Теперь в A -- младший байт, а в C -- старший. Запиши их в память.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

>Теперь в A -- младший байт, а в C -- старший. Запиши их в память.

Это от старого поста осталось. Не читай. :)

Zubok ★★★★★
()

Эмулятор ему подавай. Такие программы пишутся и проверяются на бумаге.

ip ★★★★
()
Ответ на: комментарий от Zubok

MOV M,A а страший байт MOV E,С MOV A,E STA 870 А если использовать для хранения промежуточных результатов регистровые пары? то мы сможем избавиться от переносов?

Frolic
() автор топика
Ответ на: комментарий от Zubok

а у мя тут мозг закипает нафига ">Теперь в A -- младший байт, а в C -- старший. Запиши их в память."

Frolic
() автор топика
Ответ на: комментарий от Frolic

>MOV M,A а страший байт MOV E,С MOV A,E STA 870

Вот это я не понял, что ты написал:

A -- у тебя младший байт. Его записываешь по младшему адресу (куда у тебя HL указывает). E -- у тебя старший байт. Его записываешь по старшему адресу (по адресу HL+1).

>А если использовать для хранения промежуточных результатов регистровые пары? то мы сможем избавиться от переносов?

Прости, чего? От переносов еще никто не избавлялся так просто. :)))

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Я тож непонял че сам написал, а вот точно что я понял так это по ночам буду спать!

Frolic
() автор топика
Ответ на: комментарий от Frolic

>алькаприм! осталось обЪяснить это бородатому гоблину, эт препод у нас такой!

Ага, но только если в задании исходные данные 16-битные, то программа вся становится сложнее. :) Так что надейся, что правильно списал :)

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

исходные данные вообще числа (224 110 96), которые я сам hex (224)

Frolic
() автор топика

ндаааа
используют JMP везде попало только лохи
кстати, причём адрес в HL???

lxi h,X1 ;hl=x1
lxi b,X3 ;bc=x2
lxi d,X2 ;de=x3
dad h ;hl=hl+hl
dad b ;hl=hl+bc
mov a,e
cma
mov e,a ;e=bitwise not e
mov a,d
cma
mov d,a ;d=bitwise not d
inx d ;de=de+1 (here de=-de :)
dad d ;hl=hl+de


здесь отрицательное de получается побитовой инверсией и увеличением на 1 (булеву алгебру тоже надо учить)

ЗЫ
вот и вся пестня, 16 бит

scyld
()
Ответ на: комментарий от scyld

для ленивых в байтах (hex):

21 x1.lo x1.hi
01 x2.lo x2.hi
11 x3.lo x3.hi
29
09
7b
2f
5f
7a
2f
57
13
19

scyld
()
Ответ на: комментарий от scyld

Адрес в HL одно из требований препода. по поводу булевой агебры, мы электрики, а ассемблер учим для программирования микроконтроллеров.

Frolic
() автор топика
Ответ на: комментарий от pacify

Электроснабжение эт не только трансформаторы и провода!

Frolic
() автор топика
Ответ на: комментарий от Frolic

вобщем, я написал просто и ясно. с регистровыми парами. без гемора с переносом.
дальше думай сам. к какой жопе ты прикрутишь адрес, не знаю, в задании этого нет. там воще ничего нет. ни размера переменных, ни где хранятся - ничего.


а я вообще-то физик. ассемблер правда умею с 7го класса. и применяю не только для микроконтроллеров.

scyld
()
Ответ на: комментарий от scyld

эт я задание толком не описал, вообще-то это не переменные, а просто числа (224 110 96) которые для расчета сказано переводить в hex, результат нада размещять по адресу 86F, программа должна начинаться с адреса 820, также нада обязательно воспользоваться двумя видами адресации: непосредственная и косвенно-регистровая, также ограничено количество используемых команд. это всевозможные: MVI MOV LDA STA STAX LDAX LXI LHL SHL ADD ADI SUB SUI IHR DCR DAD INX DCX

Frolic
() автор топика
Ответ на: комментарий от Frolic

org 820
lxi h,X1 ;hl=x1
lxi b,X3 ;bc=x2
lxi d,X2 ;de=x3
dad h ;hl=hl+hl
dad b ;hl=hl+bc
mov a,e
cma
mov e,a ;e=bitwise not e
mov a,d
cma
mov d,a ;d=bitwise not d
inx d ;de=de+1 (here de=-de :)
dad d ;hl=hl+de
;-----концовка может быть такая--------
;-----в конце сохраняем HL в адрес 86fh--------
shld (86fh) ;непосредственная адресация

;-----а может быть и такая--------
;-----в конце сохраняем HL в адрес 86fh--------
xchg ;меняем de<->hl
lxi hl,86fh
mov m,e ;косвенная адресация мл. байт
inx h ;hl=hl+1
mov m,d ;косвенная адресация ст. байт


сдаём, говорим спасибо :)

scyld
()
Ответ на: комментарий от scyld

>ндаааа >используют JMP везде попало только лохи

Во-первых, как тут и было замечено, задание было недоформулировано совсем. В итоге имее то, что имеем -- решение конкретного случая кратчайшим способом (одим из). Если в ТЗ что-то не оговорено -- действуем по своему усмотрению. Так?

Во-вторых, а ты знаешь, что ты без бита переноса даешь неверное решение? Ты в курсе, что эта формула при 16-битных числах может дать 18-битный результат? Где это у тебя? Пример: 2*0xFFFF+0xFFFF-0=0x2FFFD. Вот тебе и без гимора с битом переноса. Ага. А я сделал его учет и перенос в старший разряд, когда результат не помещается в сетку. И ты тоже должен был это сделать. Признаешь промашечку?

>используют JMP везде попало только лохи

Хотелось бы теперь, чтобы эта фраза была убрана. Я использовал JNC, так как использование ADC и SBB было бы многосоловнее, так как пришлось бы временно сохранять аккумулятор где-нибудь перед этой операцией.

Zubok ★★★★★
()
Ответ на: комментарий от scyld

правда можна сначала заслать в регистровую пару константу после не чего переслать ее в другую, а в эту поместить адрес?

Дошло зачем:
mov a,e
cma
mov e,a ;e=bitwise not e
mov a,d
cma
mov d,a ;d=bitwise not d
inx d ;de=de+1 (here de=-de :)
но почему нельзя просто использовать SUB D, предворительно MVI A,H?

Frolic
() автор топика
Ответ на: комментарий от Zubok

>Во-вторых, а ты знаешь, что ты без бита переноса даешь неверное решение? Ты в курсе, что эта формула при 16-битных числах может дать 18-битный результат? Где это у тебя? Пример: 2*0xFFFF+0xFFFF-0=0x2FFFD. Вот тебе и без гимора с битом переноса. Ага. А я сделал его учет и перенос в старший разряд, когда результат не помещается в сетку. И ты тоже должен был это сделать. Признаешь промашечку?

твои костыли сильно хромают.
ты сильно гонишь.
я использую 16 чтобы перекрыть 8
ты используешь 8 с костылями.

wraparound arithmetic никогда не даёт 18 бит из 16.

я тебе говорю, на асме я с 7го класса. никаких промашек.

scyld
()
Ответ на: комментарий от scyld

>твои костыли сильно хромают. >ты сильно гонишь. >я использую 16 чтобы перекрыть 8 >ты используешь 8 с костылями.

Ха-ха, не отмазывайся. Ты загружаешь 16-битные данные и сам заявил, что арифметика 16-битная. Теперь ты даешь задний ход, и говоришь, что делал для 8-битных данных. Не надо уже.

Zubok ★★★★★
()
Ответ на: комментарий от Frolic

Так не каширно. Проверять флаг переноса надо после каждой операции сложения/вычитания. Надо же! Столько лет на 580 программил. Ни фига уже не помню! Старею :(

vada ★★★★★
()
Ответ на: комментарий от scyld

Твое решение работает нормально для 8-битных. А я делал как бы общий случай, который должен распространяться на все. Даже на 32-бита. Ну нет 32-битных операций в 8080. Я предполагал вообще, что в задании слишком просто отталкиваться от 8-битных, но мне так было удобнее. Но если бы потребовалось быстро переписать для 16-битных, то все проверки заемов и переносов остались бы. Надо было бы результат хранить в 24 или 32 битах.

Zubok ★★★★★
()
Ответ на: комментарий от scyld

к сожалению да обязательно нада заслать откуда то содержимое в ячейку памяти адрес которой находится в регистровой паре!
а получается что свободной регистровой пары нет!
Это требование препода (бородатого гоблина :)

Frolic
() автор топика
Ответ на: комментарий от scyld

>wraparound arithmetic никогда не даёт 18 бит из 16.

А кто тебе сказал, что здесь требуется арифметика по модулю 256 или 65536? Здесь обычная арифметика.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

>Ппц, а с 1987 года, прикинь?

ну ты крут.

может будешь спорить, что JMP - это плохой тон?
MCU это хрен с ними, а вот x86(_64), MIPS, ARM etc.
А асм NVidia? там воще нет переходов (до некоторых пор).
А SSE/MMX?

используйте, наздоровье.
но это плохо и от этого надо отучаться.

scyld
()
Ответ на: комментарий от Frolic

>к сожалению да обязательно нада заслать откуда то содержимое в ячейку памяти адрес которой находится в регистровой паре!

перечитай мои посты, в одном из них написано вот это:

;-----а может быть и такая--------

;-----в конце сохраняем HL в адрес 86fh--------

xchg ;меняем de<->hl

lxi hl,86fh

mov m,e ;косвенная адресация мл. байт

inx h ;hl=hl+1

mov m,d ;косвенная адресация ст. байт

scyld
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.