这是我的代码,程序应该要求一个介于0-65,535之间的数字,并且它应该输出半字节形式的半字节
.model small
.data
prompt db "Input an integer in the interval [0, 65535]: $", 0
number dw 0h
digitCounter db 0h
place_value dw 0h
number_of_bits dw 0h
two db 2
.stack 4096
.code
readInt proc
mov ah, 01h ; reads a character from the keybaord and loads it into the AL register
int 21h
ret
readInt endp
; after readInt, AL has the integer itself, and AX has 0001 XXXX
newline proc
mov dl, 10
mov ah, 02h
int 21h
mov dl, 13
mov ah, 02h
int 21h
ret
newline endp
main proc
; Clearing data
mov ax, @data
mov ds, ax
; Start of main() proper
call newline
mov dx, offset prompt
mov ah, 09h
int 21h
DLOOP:
cmp digitCounter, 05h ; if we have already read 6 digits
je PROG_CONT ; we jump
call readInt ; puts the read character into the AH register
cmp al, 0Dh
je PROG_CONT
sub al, 30h ; after this point, the read character is sure to be an integer
; subtract 30h to it to get the actual value
mov ah, 0h ; makes the higher bits of ah 0
push ax ; pushes that integer into the stack
inc digitCounter
jmp DLOOP
PASSED_ONES:
dec digitCounter
add number, cx; ; adds the special case (the ones digit), to the number
cmp digitCounter, 0h
je ones_cont
inc place_value ; move to the next place value of the number (tens)
PROG_CONT:
pop cx ; pops the topmost element of the stack to register CX
cmp place_value, 0h ; at the beginning of the iteration this is known to be the ones digit
je PASSED_ONES
mov ax, 10 ; first we take the place value multiplier, e.g., tens - 10, hundreds - 100
mul place_value ; the result is stored in the DX:AX augmented register
mov bx, ax ; move the result to another register because we will use AX again for another multiplication
mov ax, cx ; now we move the popped value from the CX register to the AX register
mul bx ; AX = contains the digit, BX = contains the place value, DX:AX - result
add number, ax ; add the result to the number
mov ax, 0Ah ; first we take the place value multiplier, e.g., tens - 10, hundreds - 100
mul place_value
mov place_value, ax
dec digitCounter
jnz PROG_CONT
; after this point, the variable number contains the number itself
ones_cont:
mov ax, number
do:
div two ; after division, the remainder (the digit we want) is stored in the AH register
mov cl, ah ; we copy ah to bh so that we can use AX again
push cx ; the stack now has the digits of the number in reverse order, so when we pop it
; the first value we pop is the value of the largest place value
inc number_of_bits
mov ah, 0h ; clear out AH because AX will be used again for division
cmp al, 01h ; we continue dividing the quotient, which is stored in AL and if it's zero, we move on
jne do
continue:
inc number_of_bits
mov cx, 01h
push cx
mov ax, number_of_bits
jmp EVENING_OUT_DEM_BITS
APPEND_ZERO:
mov bl, 0h
push bx ; pushes the value '0' into the stack
inc number_of_bits
mov ax, number_of_bits
EVENING_OUT_DEM_BITS:
and ax, 03h ; we use bit masking to get the last two bits of
; the binary number, and if both of them are zero, we know that
; the number is divisible by 4
; the answer, after the logical operation, is stored in the first operand
cmp ax, 0h
jne APPEND_ZERO
; after this point, all of the zeros are even are ready to be printed to the console
call newline
jmp PRINTING_DEM_BITS
DECREASE_NUM_BITS:
dec number_of_bits
PRINTING_DEM_BITS:
pop cx ; pops the most significant bit and loads it into register DX
; now dh has the bit we want to print,
add cx, 30h ; to convert the number into it's ASCII form for printing
mov dx, cx
mov ah, 02h
int 21h
cmp number_of_bits, 0h
jne DECREASE_NUM_BITS
; End of main() proper
; Returning to ms-dos
mov ax, 4c00h
int 21h
main endp
end main
每当我输入低于512的数字时,我都会正确显示,但是当我输入一个大于或等于512的数字时,它会有一个无限循环。 我是新手,请帮忙。谢谢
答案 0 :(得分:2)
请注意,如果输入高于div two
,ah
将会销毁您可能需要的512
。如果你有AX=512
会发生什么,你似乎使用的字节大小的div会产生溢出,因为结果256
不适合8位。大概DOS会忽略生成的异常,这就是你没有意识到问题的原因。
在任何情况下,建议不要使用div
除以2,只需要一个简单的右移即可。如果向左移动,您甚至可以按正确的顺序获得数字。
答案 1 :(得分:2)
div two
执行'AL = AX / 2'。如果结果不适合AL
(> 255),则会出现“除法溢出错误”。如果是AX,则情况就是这样。 511.将师改为WORD-division。
替换
...
.data
...
two db 2
...
.code
...
do:
div two ; after division, the remainder (the digit we want) is stored in the AH register
mov cl, ah ; we copy ah to bh so that we can use AX again
push cx ; the stack now has the digits of the number in reverse order, so when we pop it
; the first value we pop is the value of the largest place value
inc number_of_bits
mov ah, 0h ; clear out AH because AX will be used again for division
cmp al, 01h ; we continue dividing the quotient, which is stored in AL and if it's zero, we move on
jne do
...
通过
...
.data
...
two dw 2 ; WORD causes a WORD-division
...
.code
...
do:
xor dx, dx
div two ; DX:AX / two -> AX, remainder DX
mov cx, dx
push cx ; the stack now has the digits of the number in reverse order, so when we pop it
; the first value we pop is the value of the largest place value
inc number_of_bits
cmp ax, 01h
jne do
...
其他地方有一个问题:512d不是0010000000001b。