x86 程序冻结 [tasm]
x86 Program Freeze [tasm]
我有这段代码(having a string of length n, build another of length n-2 as it follows: sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
),但我不明白为什么它会冻结。没有错误,我已经调试了一段时间了,但我无法确定是不是算法的问题。
prints macro number
local decompose, pops
mov bx,10
mov al, number
mov cx,0
decompose: ;pushing digits to the stack
inc cx
mov ah,0
div bl
mov dl,ah ; remainder - last digit
add dx,48 ; to transform it in its char version
push dx
cmp al,0
jnz decompose
pops: ; pop digits off the stack
pop dx
mov ah,2h
int 21h
loop pops
; pretty spacing
mov dl,' '
mov ah,2h
int 21h
endm
data segment para public 'data'
sir db 5, 10, 12, 4, 3
n equ $-sir
sir2 db n-2 dup(0)
data ends
code segment para public 'code'
start proc far
assume cs:code,ds:data
push ds
xor ax,ax
push ax
mov ax,data
mov ds,ax
mov si,0
mov dx,3
mov cx,n
sub cx,2
l1:
mov ah,0
mov al,sir[si]
add al,sir[si+1]
add al,sir[si+2] ;sum of 3 numbers
div dx ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
mov sir2[si],al
inc si
cmp si,cx
jbe l1
mov si,0
l2:
prints sir2[si]
inc si
loop l2
ret
start endp
code ends
end start
有人可以帮忙吗?
DIV r/m16
的描述是 "Unsigned divide DX:AX
by r/m16
"。换句话说,分子是由 DX
和 AX
中的位组合而成的 32 位值。
如果商变得太大而无法容纳在 AX
你得到一个例外。为避免这种情况,您应该在除法之前清除 DX
(即 mov dx,0
或 xor dx,dx
)。显然这也意味着你不能使用DX
作为分母。
改变
div dx ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
至
div dl ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
(见迈克尔的回答)。
宏是在调用宏的地方插入"as is"的一段代码。宏 prints
更改 CX
,您需要为 loop l2
保持不变。重写循环:
mov si, 0
mov di, cx
l2:
prints sir2[si]
inc si
dec di
jnz l2
顺便说一句:不要忘记定义堆栈:
_STACK SEGMENT PARA STACK 'STACK'
dw 1024 dup (?)
_STACK ENDS
您的程序可能会死机,因为您进行的迭代次数过多!
cmp si,cx
jbe l1
这给出了 4 次迭代,而 sir2 只有 3 个字节的存储空间!使用 jb l1
我有这段代码(having a string of length n, build another of length n-2 as it follows: sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
),但我不明白为什么它会冻结。没有错误,我已经调试了一段时间了,但我无法确定是不是算法的问题。
prints macro number
local decompose, pops
mov bx,10
mov al, number
mov cx,0
decompose: ;pushing digits to the stack
inc cx
mov ah,0
div bl
mov dl,ah ; remainder - last digit
add dx,48 ; to transform it in its char version
push dx
cmp al,0
jnz decompose
pops: ; pop digits off the stack
pop dx
mov ah,2h
int 21h
loop pops
; pretty spacing
mov dl,' '
mov ah,2h
int 21h
endm
data segment para public 'data'
sir db 5, 10, 12, 4, 3
n equ $-sir
sir2 db n-2 dup(0)
data ends
code segment para public 'code'
start proc far
assume cs:code,ds:data
push ds
xor ax,ax
push ax
mov ax,data
mov ds,ax
mov si,0
mov dx,3
mov cx,n
sub cx,2
l1:
mov ah,0
mov al,sir[si]
add al,sir[si+1]
add al,sir[si+2] ;sum of 3 numbers
div dx ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
mov sir2[si],al
inc si
cmp si,cx
jbe l1
mov si,0
l2:
prints sir2[si]
inc si
loop l2
ret
start endp
code ends
end start
有人可以帮忙吗?
DIV r/m16
的描述是 "Unsigned divide DX:AX
by r/m16
"。换句话说,分子是由 DX
和 AX
中的位组合而成的 32 位值。
如果商变得太大而无法容纳在 AX
你得到一个例外。为避免这种情况,您应该在除法之前清除 DX
(即 mov dx,0
或 xor dx,dx
)。显然这也意味着你不能使用DX
作为分母。
改变
div dx ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
至
div dl ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
(见迈克尔的回答)。
宏是在调用宏的地方插入"as is"的一段代码。宏 prints
更改 CX
,您需要为 loop l2
保持不变。重写循环:
mov si, 0
mov di, cx
l2:
prints sir2[si]
inc si
dec di
jnz l2
顺便说一句:不要忘记定义堆栈:
_STACK SEGMENT PARA STACK 'STACK'
dw 1024 dup (?)
_STACK ENDS
您的程序可能会死机,因为您进行的迭代次数过多!
cmp si,cx
jbe l1
这给出了 4 次迭代,而 sir2 只有 3 个字节的存储空间!使用 jb l1