Язык ассемблера переключается на флаги

В настоящее время я получил задание, в котором мне нужно кодировать на ассемблере, где вы берете пользовательский ввод, чтобы получить шестнадцатеричное 4-значное значение и преобразовать его в двоичное, а затем, после получения двоичного значения, вы должны преобразовать его в число месяца и года, где первые 7 цифр - год, следующие четыре - месяц, а последние 5 - день.

Я все преобразовал в двоичный файл и имею представление о том, как получить его из двоичного в обычные целочисленные значения для года, месяца и дня. Когда я запускаю свой код, вывод 0/0/0, Я не уверен, что это там, где я испортил свое смещение или что-то еще. Не могли бы вы, ребята, взглянуть и дать мне понять, где исправить? В коде, который я вставляю, я добавляю только calcYear и решил, что смогу это выяснить, а затем поработать над остальным.

Мой код:

firstLine:

    call crlf
    mov si, offset programOne
    mov cx, programOneLen
    call putStrng       ;displays 'Program by Joe Remaklus'

    call crlf
    call crlf

    call inputVal   ;prompt for hex input
    call putBin ;display the value in AX as binary
    call crlf
    call calcYear   ;display the year of the first 7 binary digits.
    mov si, offset slash
    mov cx, slashLen
    call putStrng
    call calcMonth  ;display the month of the next 4 binary digits.
    mov si, offset slash
    mov cx, slashLen
    call putStrng
    call calcDay    ;display the day of the next 5 binary digits.
    call crlf

    call inputVal
    call putBin






    mov ah,04c
    int 021




prompt db 'Enter a 4-digit hex value'

lenPrompt = $-prompt


inputVal:

    push si, cx

    mov  si, offset prompt

    mov  cx, lenPrompt

    call putStrng

    call crlf

    call getHex

    call crlf

    pop  cx, si

    ret
;---------------------------------------------------------------

putBin:

    push ax, cx, dx

    mov  cx, 16     ;number of bits to display

  putBinLoopTop:

    mov  dl, '0'        ;assume bit to display is zero

    shl  ax, 1      ;shift bit to display into Carry Flag

    jnc  putBinSkipInc  ;if the top bit was zero skip the inc

    inc  dl         ;else inc DL to '1'

  putBinSkipInc:

    call putChar        ;display the character in DL

    loop putBinLoopTop  ;continue until 16 bits are displayed

    pop  dx, cx, ax

    ret
;---------------------------------------------------------------

calcYear:

    mov year, 0

    mov si, 0

    shl ax, 1
    adc si, 0
    iMul onetwoeight
    add year, si
    mov si, 0 

    shl ax, 1
    adc si, 0
    iMul sixfour
    add year, si
    mov si, 0

    shl ax, 1
    adc si, 0
    iMul threetwo
    add year, si
    mov si, 0

    shl ax, 1
    adc si, 0
    iMul sixteen
    add year, si
    mov si, 0

    shl ax, 1
    adc si, 0
    iMul eight
    add year, si
    mov si, 0


    shl ax, 1
    adc si, 0
    iMul four
    add year, si
    mov si, 0


    shl ax, 1
    adc si, 0
    iMul two
    add year, si
    mov si, 0


    shl ax, 1
    adc si, 0
    iMul one
    add year, si
    mov si, year
    add si, 1980
    call putPos
ret

1 ответ

Решение

Если я вас правильно понимаю, при вводе calcYear ваш "топор" выглядит так в двоичном виде: гггг гггг мммд дддд

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

Вместо этого я покажу вам, как по-другому относиться к этой проблеме.

Давайте попробуем покопаться в корыте и понять это:

    ; ax is encoded as this: yyyy yyym mmmd dddd
    push ax
    push ax ; store the encoded value at stack twice
    ; extract "day" value
    and ax,01Fh  ;only "d" bits will survive
    mov [day],ax
    ; extract "month" value
    pop ax ; restore encoded input
    shr ax,5 ; shift ax by number of "d" bits
    and ax,0Fh ; only shifted "m" bits
    mov [month],ax
    ; extract "year" value
    pop ax ; restore encoded input
    shr ax,5+4 ; shift ax by number of "d" and "m" bits
    ; no need to "and", as "shr" did fill upper bits by zeroes
    add ax,1980 ; so "0" encoded year is 1980? (deducted from OP source)
    mov [year],ax
    ret

Я надеюсь, что это даст вам новые идеи о том, как работать с определенными частями. Иметь ввиду and/or хорошо замаскировать вещи, которые вас интересуют и shr/sar/sal/shl/ror/rol/rcr/... хорошо поставить его в желаемое положение. xor может использоваться для исправления результата (при необходимости), test как and но получение только флагов обновляет регистр, а затем есть несколько более ориентированных на биты инструкций x386+ (или 486?), которые несколько "продвинуты" и могут сэкономить вам 2-3 комбинации команд из тех основ, которые я упоминал ранее. Таким образом, вы можете спокойно их игнорировать, если вы полностью понимаете их и можете согнуть что угодно с ними по своему усмотрению.

Другие вопросы по тегам