无法找出错误的位置。测试我的汇编程序代码并没有给我正确答案

时间:2017-11-01 16:15:51

标签: assembly emu8086

我必须创建一个小程序来执行公式,并使用汇编语言和EMU8086微处理器仿真器给出正确的答案。 我编写了它,有一些错误,我成功修复它们但它给出的答案是不正确的。我花了很多时间试图解决这个问题,但不幸的是,没有成功。我需要帮助。

公式:

y = |x+b|                        if c = a*x

y = a^2 - 3*b                    if c < a*x

y = ] (2*c-a) / (c+a*x) [        if c > a*x

] [ - 意味着只带出整数而不是残余。

设置变量:

a=3
b=4
c=6
array  x[] = 2,3,1,4,5
array  y[] is the answers

所以这是基本点。这里它计算a * x的乘法并将结果与​​变量c进行比较。根据结果​​,它应切换到不同的计算。

cikl:      ; cycle starts 
      XOR dx,dx   
      MOV bx,a ; bx=a           
      MOV al,x[si]
      XOR ah,ah
      MUL bx;
      JC kl1; overflow
      CMP ax,0 ; compare ax with 0    
      JB f2   ; if a*x < 0 jump to f2  
      JA f3   ; if a*x > 0 jump to f3

所以它应该给我这样的结果:

x=2 y=6
x=3 y=-3 (overflow error should be here)
x=1 y=1
x=4 y=8
x=5 y=9

但目前它打印出来: screenshot

代码:

; task:  | x+b |                        if c= a*x
;        a^2 - 3*b                      if c< a*x
;        ] ( 2c-a ) / ( c+ax ) [        if c> a*x 
;        a=DW b=DB c=DB x=DB y=DW
;

stekas  SEGMENT STACK
DB 256 DUP(0)
stekas  ENDS

duom    SEGMENT
a DW 3;
b DB 4;
c DB 6;
x DB 2,3,1,4,5
kiek = ($-x);
y DW kiek dub(0AAh)
isvb    DB 'x=',6 dup (?), ' y=',6 dup (?), 0Dh, 0Ah, '$'
perp    DB 'Perpildymas', 0Dh, 0Ah, '$'
daln    DB 'Dalyba is nulio', 0Dh, 0Ah, '$'
netb    DB 'Netelpa i baita', 0Dh, 0Ah, '$'
spausk  DB 'Skaiciavimas baigtas, spausk bet kuri klavisa,', 0Dh, 0Ah, '$'     
duom    ENDS

prog    SEGMENT
assume ss:stekas, ds:duom, cs:prog
pr:
  MOV ax, duom ;move data to ax
  MOV ds,ax
  XOR si,si   ; si=0
  XOR di,di   ; di = 0; 
  MOV cx,kiek ; cx = kiek
  JCXZ pab   ; if kiek = 0 jump to the end 
cikl:      ; cycle starts 
  XOR dx,dx   
  MOV bx,a ; bx=a           
  MOV al,x[si]
  XOR ah,ah
  MUL bx;
  JC kl1; overflow
  CMP ax,0 ; compare ax with 0    
  JB f2   ; if a*x < 0 jump to f2  
  JA f3   ; if a*x > 0 jump to f3

; part of task:  | x+b |                 if c= a*x    
f1:                     
  MOV al, b
  MOV dl, x[si]
  ADD al, x[si]
  JC kl1
  JMP re

;            a^2 - 3*b               if c< a*x  
f2:
  MOV ax, a
  XOR ah, ah
  MOV bl, al
  MUL bl
  JC kl1; overflow
  MOV dx, ax
  XOR ax, ax
  XOR bl, bl
  MOV bl, 3
  MOV al, b
  XOR ah, ah
  MUL bl
  JC kl1; overflow
  SUB dx, ax
  XOR ax, ax
  MOV ax, dx
  JMP re 
;            ] ( 2c-a ) / ( c+ax ) [ if c> a*x   
f3:
 MOV al, c
 XOR ah, ah
 MOV dl, 2
 MUL dl
 JC kl1; overflow
 XOR dl, dl
 MOV dx, a
 SUB ax, dx
 CMP ax, 0
 JE kl2; number can be only positive
 XOR dl, dl
 MOV bx, ax
 XOR ax, ax 
 MOV dx, a ; dx=a           
 MOV al, x[si]
 XOR ah, ah
 MUL dx;
 JC kl1;overflow
 XOR dx, dx
 MOV dl, c
 ADD ax, dx
 JC kl1;overflow
 MOV dx, ax
 MOV ax, bx
 MOV bx, dx
 XOR dx, dx
 DIV bx
 JC kl1
 XOR ah, ah
re:
CMP ax, 0     ;does result fit
JE ger
JMP kl3
ger:    
MOV y[di], ax
INC si
;INC si
;INC di 
INC di
LOOP cikl
pab:
;bring out results to screen
;============================
XOR si, si
XOR di, di
MOV cx, kiek
JCXZ is_pab
is_cikl: 
MOV al, x[si]  ; number x is in ax reg. 
XOR ah,ah
PUSH ax
MOV bx, offset isvb+2
PUSH bx
CALL binasc
MOV ax, y[di]
;XOR ah, ah        ; number y is in ax reg.
PUSH ax
MOV bx, offset isvb+11
PUSH bx
CALL binasc

MOV dx, offset isvb
MOV ah, 9h
INT 21h
;============================
INC si
;INC si
iNC di   
;INC di
LOOP is_cikl
is_pab:
;===== PAUSE ===================
;===== press any key ===
LEA dx, spausk
MOV ah, 9
INT 21h
MOV ah, 0
INT 16h
;============================
MOV ah, 4Ch   ; program ends, come back to OS
INT 21h
;============================

kl1:    LEA dx, perp
MOV ah, 9
INT 21h
XOR al, al
JMP ger
kl2:    LEA dx, daln
MOV ah, 9
INT 21h
XOR al, al
JMP ger
kl3:    LEA dx, netb
MOV ah, 9
INT 21h
XOR al, al
JMP ger

; convert number to decimal and save
; ASCII kode. Parametrai perduodami per steka 
; in ASCII code. Parameters pass through stack
; Fist parameter ([bp+6])- converted number
; Second parameter ([bp+4])- place for result

binasc    PROC NEAR
PUSH bp
MOV bp, sp
; saving used registers
PUSHA
; Filling line with spaces
MOV cx, 6
MOV bx, [bp+4] 
tarp:    MOV byte ptr[bx], ' '
INC bx
LOOP tarp
; number is prepared for DIV is 10
MOV ax, [bp+6]
MOV si, 10
val:    XOR dx, dx
DIV si
;  remnant to ASCII code
ADD dx, '0'   ; can be--> ADD dx, 30h
;  write number to the end of the line
DEC bx
MOV [bx], dl
; count number of converted symbols
INC cx
; do we need to DIV more ?
CMP ax, 0
JNZ val

POPA
POP bp
RET
binasc    ENDP
prog    ENDS
END pr

1 个答案:

答案 0 :(得分:3)

在汇编中,没有任何数字低于零,所以你的程序永远不会跳转到f2。

CMP ax,0 ; compare ax with 0    
JB f2   ; if a*x < 0 jump to f2  
JA f3   ; if a*x > 0 jump to f3

根据Sign(a*x),您希望获得3种不同的结果 为了实现这一目标,您需要将* x中的产品视为签名号码。在汇编编程中,您可以使用条件跳转的{strong>签名版本(jljg,...)来完成此操作。您已使用未签名版本(jbja,...)。

CMP ax,0 ; compare ax with 0    
JL f2   ; if a*x < 0 jump to f2  
JG f3   ; if a*x > 0 jump to f3

该部门没有定义任何标志。

 XOR dx, dx
 DIV bx
 JC kl1
 XOR ah, ah
re:

JC kl1将根据进位标志(CF)的当前值跳转,但由于DIV指令会使所有标志未定义,因此会出现这种情况。不知道CF在这个程序中将会是什么。可能是前面的xor dx, dx仍然清楚,但并非总是如此。如果INTEL记录了DIV指令以保留未修改的标志,那么情况就是如此。

底线是你的程序会表现不正常。