Язык ассемблера переключается на флаги
В настоящее время я получил задание, в котором мне нужно кодировать на ассемблере, где вы берете пользовательский ввод, чтобы получить шестнадцатеричное 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 комбинации команд из тех основ, которые я упоминал ранее. Таким образом, вы можете спокойно их игнорировать, если вы полностью понимаете их и можете согнуть что угодно с ними по своему усмотрению.