【发布时间】:2016-04-28 02:27:35
【问题描述】:
我目前有一个任务,我必须用汇编语言编写代码,你需要用户输入来获得一个 4 位十六进制值并将其转换为二进制,然后在你获得二进制值后,你必须将其转换为一个月和年份,其中前 7 位数字是年份,接下来的 4 位是月份,最后 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
【问题讨论】:
-
您是否在调试器中单步执行此操作以确保 regs 中的值符合您的预期?你说得对,
shl ax/adc si, 0相当于在 ax 中测试一点,然后使用setcc。 (例如xor dx,dx/bt ax, 3/setc dl,除非这不会修改ax)我完全不相信您的imuls 有意义。也许这是一种非常迂回的做事方式,但我还没弄清楚是什么。你知道乘以 2 的幂和移位是一样的,对吧?此外,您可以一直将year保留在si中,而不是一直使用内存目标。 -
由于代码中缺少 cmets 或对确切年份 calc 应该实现的算法的描述而被否决。对我来说,添加这些位看起来有点奇怪(popcnt)。也因为没有一个最小的例子来说明你遇到的问题。这仍然是很多代码。如果您改进了问题,请回复,我可能会删除我的反对票。
-
没有。使用调试器来确定您的代码哪里出错了,如果您看不到为什么会发生这种特定行为,请再次询问更具体的内容,而不是“...输入要纠正的地方”。
标签: assembly x86 shift carryflag irvine16