Сборка Motorola 68000 сравнение номеров

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

start:  initIO                  * Initialize (required for I/O)
    setEVT          * Error handling routines
*   initF           * For floating point macros only       

    linein  buffer          *reads in values
    cvta2   buffer,#1       *provided macro to convert ascii to num, read first digit only
    move.b  D0,D1           *Store value in D1
    cvta2   buffer+2,#2     *read the next two digits after space
    move.b  D0,D2           *store
    add.b   D1,D2           *add them together (I can probably use just one register here)

вот беда:

for:    cmp.w   week, D2 *<<<<< This is saying invalid syntax, I want to see if the number provided is greater than 7, if not branch out to the next section

/беда

    ble done
    subq.w  #7,D2        *If num>7, sub 7

done:   

    lineout dmsg

        break                   * Terminate execution
*
*----------------------------------------------------------------------
*       Storage declarations

buffer: dc.b    80
dmsg:   dc.b    'Done',0
week:   dc.b    $7    *If combined value is greater than this, sub 7
*These are the values to check against to get correct reply
sun:    dc.b    $1
mon:    dc.b    $2
tues:   dc.b    $3
weds:   dc.b    $4
thurs:  dc.b    $5
fri:    dc.b    $6
sat:    dc.b    $7
*These are the responses for the output
sunr:   dc.b    'Sunday',0
monr:   dc.b    'Monday',0
tuesr:  dc.b    'Tueday',0
wedsr:  dc.b    'Wednesday',0
thursr: dc.b    'Thursday',0
frir:   dc.b    'Friday',0
satr:   dc.b    'Saturday',0

        end

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

Я пытался использовать различные формы cmp (cmpa, cmpi.w/l и т. д.), но не могу найти метод, позволяющий сравнить эти два значения. Должен ли я загружать значение, которое я назвал «неделя», в регистр, прежде чем пытаться его сравнить или что-то в этом роде?

Примеры ввода/вывода:

Вход:

1 10

Вывод:

"Среда"

Любое понимание ценится. Спасибо за ваше время.


person Jeremy H.    schedule 18.10.2017    source источник
comment
Пожалуйста, не редактируйте ответ в вопросе; опубликуйте это как ответ. (и откатите свое редактирование.)   -  person Peter Cordes    schedule 20.10.2017
comment
Даже несмотря на то, что проблемный код все еще существует и отделен от рабочего кода? Сможет сделать.   -  person Jeremy H.    schedule 20.10.2017
comment
Да, ответ на вопрос в вопросе побеждает формат вопросов и ответов и ставит ваш собственный ответ в особое место над другими, где голосование не может поднять лучшие ответы наверх. (Едва ли это имеет значение для вопросов по отладке, поскольку они, к сожалению, редко имеют большую ценность в будущем; другим людям трудно искать и находить правильный вопрос, когда они тоже не знают, в чем их проблема.) В любом случае, спасибо за приведение в порядок вашего вопроса. и добро пожаловать в Stack Overflow.   -  person Peter Cordes    schedule 20.10.2017


Ответы (2)


Вы пытаетесь выполнить сравнение с неподдерживаемым режимом адресации (в вашем примере операнд "неделя" является не непосредственным значением, а адресом памяти).

Чтобы сравнить D2 с 7, вы можете использовать cmpi (сравните немедленно):

cmpi.b #7,d2

Если вам нужно, чтобы операнд был переменной, вы должны сначала загрузить его в регистр:

lea week,a0
...
cmp.b (a0),d2

Также убедитесь, что размер операнда в инструкции cmp соответствует размеру ваших данных.

person MutenFuzz    schedule 19.10.2017
comment
Это загружает адрес метки в a0, поэтому я думаю, что мне просто нужно выяснить правильный синтаксис, чтобы вместо этого загрузить значение по этому адресу, и я должен быть хорошим. - person Jeremy H.; 19.10.2017
comment
@ДжеремиХ. На самом деле вам не нужно изменять week во время выполнения, поэтому вместо того, чтобы хранить его в памяти, определите его как константу ассемблера. (Я забыл синтаксис m68k, но что-то вроде week equ 7, поэтому, когда вы пишете cmpi.w week, d2, это эквивалентно написанию cmpi.w #7, d2. - person Peter Cordes; 19.10.2017
comment
@JeremyH.: Кстати, режимы адресации m68k: moss. csc.ncsu.edu/~mueller/codeopt/codeopt00/notes/addmode.html. Абсолютные (и относительные для ПК) режимы адресации существуют. Может быть, ваш ассемблер ругается, потому что за меткой week следует dc.b, но вы выполняете загрузку слов? - person Peter Cordes; 19.10.2017
comment
@PeterCordes Спасибо за руководство. Наконец-то я поставил программу на две ноги. Еще предстоит выполнить некоторую оптимизацию, но это выходит за рамки этого форума. Я закончил тем, что использовал вашу экипировку в течение недели, и я проверю ваш веб-сайт. Еще раз спасибо! - person Jeremy H.; 19.10.2017
comment
@JeremyH.: хех, это не мой веб-сайт, просто первое попадание в Google по запросу m68k addressing modes. Удобно, что m68k equ использует тот же синтаксис, что и NASM. Первым языком ассемблера, который я изучил, был m68k, когда у меня была Atari ST, но я не использовал его почти 20 лет. - person Peter Cordes; 19.10.2017

Изменить(Рабочий код для проблемы с оговоркой, что он не оптимизирован):

start:  initIO                  * Initialize (required for I/O)
    setEVT          * Error handling routines
*   initF           * For floating point macros only    

    linein  buffer
    cvta2   buffer,#1   
    move.l  D0,D1
    cvta2   buffer+2,#2
    move.l  D0,D2
    add.l   D1,D2    

    divu.w  #$0007,D2   

    lsr.l   #$08,D2 *Shift remainder
    lsr.l   #$08,D2    

    move.w  sun,A2
    cmp.w   A2,D2
    BNE monday
    lineout sunr
    BEQ end

monday: 
    move.w  mon,A2
    cmp.w   A2,D2
    BNE tuesda
    lineout monr
    BEQ end    

tuesda: 
    move.w  tues,A2
    cmp.w   A2,D2
    BNE wednes
    lineout tuesr
    BEQ end    

wednes: 
    move.w  weds,A2
    cmp.w   A2,D2
    BNE thursd
    lineout wedsr
    BEQ end    

thursd: 
    move.w  thurs,A2
    cmp.w   A2,D2
    BNE friday
    lineout thursr
    BEQ end    

friday: 
    move.w  fri,A2
    cmp.w   A2,D2
    BNE saturd
    lineout frir
    BEQ end    

saturd: 
    lineout satr
    BEQ end    

end:    
        break                   * Terminate execution
*
*----------------------------------------------------------------------
*       Storage declarations

buffer: dc.b    80
wkmsg:  dc.w    'The day of the week is '
week:   equ $7
sun:    dc.w    $1
mon:    dc.w    $2
tues:   dc.w    $3
weds:   dc.w    $4
thurs:  dc.w    $5
fri:    dc.w    $6
sat:    dc.w    $7
sunr:   dc.w    'Sunday',0
monr:   dc.w    'Monday',0
tuesr:  dc.w    'Tueday',0
wedsr:  dc.w    'Wednesday',0
thursr: dc.w    'Thursday',0
frir:   dc.w    'Friday',0
satr:   dc.w    'Saturday',0

        end
person Jeremy H.    schedule 19.10.2017
comment
BEQ end — это условная ветвь, верно? Конечно, это должен быть безусловный переход, а не условный по флагам, оставленным lineout. - person Peter Cordes; 20.10.2017
comment
Вы уже знаете, что это не оптимизировано, но больше всего бросается в глаза то, что вы можете выполнить одну проверку границ, а затем поиск в таблице из таблицы указателей на строки. Таким образом, вместо $1, $2 и т. д. в памяти у вас будет dc.w $sunr, $monr, ... (или любой другой правильный синтаксис для использования адреса другой метки в качестве данных), поэтому вы выполняете индексированную загрузку в A2 или что-то еще, затем lineout A2. - person Peter Cordes; 20.10.2017
comment
Кроме того, вам действительно не нужно хранить $1 в файле dc.w. Константы 1-7 также могут быть equ константами. Кроме того, я думаю, вы забыли , 0 после wkmsg, но если количество символов нечетное, то использование dc.w спасло вас от себя, дополнив нулем до целого числа слов. - person Peter Cordes; 20.10.2017