简体   繁体   中英

Assembly code to convert binary to decimal not outputting correct answers

I am writing a program in a custom assembly language for my university assignment, and it is supposed to convert binary into decimal using ASCII. Here is my code:

// Clear memory
MOV BX, 0x00
MOV [0xA0],BX
MOV [0xA1],BX
MOV [0xA2],BX
MOV [0xA3],BX
MOV [0xA4],BX

// If equal to 1, write 8 to A0. Else move on
CALL readtobx
CMP BX,0x31
JEQ bxisone_eight

// If equal to 0, write nothing. Else, write E and halt
CMP BX,0x30
JNE error
JMP wrote8bit

bxisone_eight:
MOV BX,0x08
MOV [0xA0],BX
wrote8bit:

// If equal to 1, write 4 to A1. Else move on
CALL readtobx
CMP BX,0x31
JEQ bxisone_four

// If equal to 0, write nothing. Else, write E and halt
CMP BX,0x30
JNE error
MOV BX,0x00
CALL writebx
JMP wrote4bit

bxisone_four:
MOV BX,0x04
MOV [0xA1],BX
JMP wrote4bit

wrote4bit:

// If equal to 1, write 2 to A2. Else move on
CALL readtobx
CMP BX,0x31
JEQ bxisone_two

// If equal to 0, write nothing. Else, write E and halt
CMP BX,0x30
JNE error
MOV BX,0x00
CALL writebx
JMP wrote2bit

bxisone_two:
MOV BX,0x02
MOV [0xA2],BX
JMP wrote2bit

wrote2bit:
// If equal to 1, write 1 to A3. Else move on
CALL readtobx
CMP BX,0x31
JEQ bxisone_one

// If equal to 0, write nothing. Else, write E and halt
CMP BX,0x30
JNE error
MOV BX,0x00
CALL writebx
JMP wrote4bit

bxisone_one:
MOV BX,0x01
MOV [0xA3],BX
JMP wrote1bit

wrote1bit:

// Add all the numbers together 
MOV BX,0x00
ADD BX,[0xA0]
ADD BX,[0xA1]
ADD BX,[0xA2]
ADD BX,[0xA3]

MOV AX,0x0A
CMP AX,BX
JGE write10first
ADD BX,0x30
CALL writebx

HALT

error:
  MOV BX,0x45
  CALL writebx
  HALT

writebx:
  MOV AX,[0xF2]
  CMP AX,0x0
  JNE writebx
  MOV [0xF0],BX 
  MOV AX,0x10
  MOV [0xF2],AX  // Set OSR to 1
  RET

readtobx:
  MOV AX,[0xF5]
  CMP AX,0x00 // See if value is zero
  JEQ readtobx
  MOV BX,[0xF3]
  MOV AX,0x01
  MOV [0xF5],BX
  MOV AX,0x00
  MOV [0XF5],AX
  RET

write10first:
   SUB BX,0x0A
   MOV BX,[0xA4]
   ADD BX,0x30
   CALL writebx
   MOV BX,[0xA4]
   ADD BX,0x30
   CALL writebx
   HALT

However, I almost never seem to get the result I was looking for.
To clarify, the flags writebx and readtobx are to output the result of BX to the console using the code. That isn't the issue.

Here are the opcodes:

00  NOP     
01  MOV AX,BX
02  MOV AX,[BX]
03  MOV AX,[AX]
04  MOV AX,SP
05  MOV AX,byte
06  MOV AX,[byte]
07  MOV AX,word
08  MOV AX,[word]
09  MOV BX,AX
0A  MOV BX,[AX]
0B  MOV BX,[BX]
0C  MOV BX,SP
0D  MOV BX,byte
0E  MOV BX,[byte]
0F  MOV BX,word
10  MOV BX,[word]
11  MOV SP,AX
12  MOV SP,BX
13  MOV SP,byte
14  MOV SP,[byte]
15  MOV SP,word
16  MOV SP,[word]
17  MOV [AX],BX
18  MOV [BX],AX
19  MOV [byte],AX
1A  MOV [word],AX
1B  MOV [byte],BX
1C  MOV [word],BX
1D  MOV [byte],SP
1E  MOV [word],SP
20  ADD AX,byte
21  ADD AX,[byte]
22  ADD AX,BX
23  ADD BX,byte
24  ADD BX,[byte]
25  ADD BX,AX
28  SUB AX,byte
29  SUB AX,[byte]
2A  SUB AX,BX
2B  SUB BX,byte
2C  SUB BX,[byte]
2D  SUB BX,AX
30  OR AX,byte
31  OR AX,[byte]
32  OR AX,BX
33  OR BX,byte
34  OR BX,[byte]
35  OR BX,AX
36  AND AX,byte
37  AND AX,[byte]
38  AND AX,BX
39  AND BX,byte
3A  AND BX,[byte]
3B  AND BX,AX
40  MUL AX,byte
41  MUL BX,byte
42  MUL AX,BX
43  MUL BX,AX
44  MUL AX,[byte]
45  MUL BX,[byte]
46  DIV AX,byte
47  DIV BX,byte
48  DIV AX,BX
49  DIV BX,AX
4A  DIV AX,[byte]
4B  DIV BX,[byte]
4C  MOD AX,byte
4D  MOD BX,byte
4E  MOD AX,BX
4F  MOD BX,AX
50  MOD AX,[byte]
51  MOD BX,[byte]
52  SHL AX
53  SHL BX
54  SHR AX
55  SHR BX
56  INC AX
57  INC BX
58  DEC AX
59  DEC BX
5A  NEG AX
5B  NEG BX
5C  NOT AX
5D  NOT BX
60  CMP AX,byte
61  CMP AX,[byte]
62  CMP AX,BX
63  CMP BX,byte
64  CMP BX,[byte]
65  CMP BX,AX
70  JMP AX
71  JMP BX
72  JMP [AX]
73  JMP [BX]
74  JMP byte
75  JMP [byte]
76  JMP word
77  JMP [word]
78  JEQ AX
79  JEQ [AX]
7A  JEQ BX
7B  JEQ [BX]
7C  JEQ byte
7D  JEQ [byte]
7E  JEQ word
7F  JEQ [word]
80  JNE AX
81  JNE [AX]
82  JNE BX
83  JNE [BX]
84  JNE byte
85  JNE [byte]
86  JNE word
87  JNE [word]
88  JL AX
89  JL [AX]
8A  JL BX
8B  JL [BX]
8C  JL byte
8D  JL [byte]
8E  JL word
8F  JL [word]
90  JGE AX
91  JGE [AX]
92  JGE BX
93  JGE [BX]
94  JGE byte
95  JGE [byte]
96  JGE word
97  JGE [word]
A0  PUSH AX
A1  PUSH BX
A2  PUSH byte
A3  PUSH [byte]
A4  PUSH word
A8  POP AX
A9  POP BX
B0  CALL AX
B1  CALL BX
B2  CALL [AX]
B3  CALL [BX]
B4  CALL byte
B5  CALL [byte]
B6  CALL word
B7  CALL [word]
BA  RET
EE  HALT

I understand it's a big ask but any and all help would be appreciated!

I've tried rewriting my code multiple times, changing configurations and others, but nothing I do seems to work.

Review

// If equal to 0, write nothing. CMP BX,0x30 JNE error MOV BX,0x00 CALL writebx

For the 4-bit, 2-bit, and 1-bit you output a null byte in case the inputted digit is "0". Why is this? You don't do it for the 8-bit. It contradicts your comment.

 JMP wrote4bit wrote4bit: ... JMP wrote2bit wrote2bit: ... JMP wrote1bit wrote1bit:

Jumping to a label that immediately follows is always a redundant operation. The execution can just fall through.

 MOV AX,0x0A CMP AX,BX JGE write10first

This code works the other way round. If 10 is greater or equal to the number, it would mean the number is less than 10 and you would not want to prepend a "1" digit.
No need to use AX anymore, you can compare BX to a byte:

CMP  BX,0x0A
JGE  write10first
 MOV AX,0x01 MOV [0xF5],BX MOV AX,0x00 MOV [0XF5],AX

Why does this code load AX but then writes BX? Either MOV AX,0x01 is redundant or MOV [0xF5],BX is doing the wrong thing.

 SUB BX,0x0A MOV BX,[0xA4] ADD BX,0x30 CALL writebx MOV BX,[0xA4] ADD BX,0x30 CALL writebx

The subtraction by 0x0A is lost immediately by the following load of BX. And the 0xA4 location only got initialized at 0, so this code will output "00" instead of the "1?" that you need.
Next code can work:

MOV [0xA4],BX
MOV BX,0x31
CALL writebx
MOV BX,[0xA4]
ADD BX,0x26        // -10 +48 is +38
CALL writebx

Rewrite

Because I see that your code repeats itself a lot, I decided to write this version that uses a loop and delegates the input of the binary digit to a subroutine. My code also does not store the 4 digits in 4 separate memory variables but rather adds the weight of the digits as it goes.

 MOV  BX,0x00
 MOV  [0xA0],BX   // result = 0
 MOV  BX,0x08
nextdigit:
 CALL inputdigit  // -> BX
 SHR  BX          // 8 -> 4 -> 2 -> 1 -> 0
 CMP  BX,0x00
 JNE  nextdigit

 MOV  BX,[0xA0]   // result is [0,15]
 CMP  BX,0x0A
 JL   onedigit
twodigits:
 MOV  BX,0x31     // print "1"
 CALL writebx
 MOV  BX,[0xA0]   // result is [10,15]
 SUB  BX,0x0A
onedigit:
 ADD  BX,0x30
 CALL writebx
 HALT

// IN (BX) OUT (BX)
inputdigit:
 MOV  [0xA1],BX   // temp is {8,4,2,1}
 CALL readtobx
 CMP  BX,0x30
 JEQ  done        // "0" does not add anything
 CMP  BX,0x31
 JNE  error
 MOV  BX,[0xA1]   // "1" adds one of {8,4,2,1}
 ADD  [0xA0],BX
done:
 MOV  BX,[0xA1]
 RET

error:
 MOV  BX,0x45     // "E"
 CALL writebx
 HALT

writebx:
 MOV  AX,[0xF2]
 CMP  AX,0x00
 JNE  writebx
 MOV  [0xF0],BX 
 MOV  AX,0x10
 MOV  [0xF2],AX   // Set OSR to 1
 RET

readtobx:
 MOV  AX,[0xF5]
 CMP  AX,0x00     // See if value is zero
 JEQ  readtobx
 MOV  BX,[0xF3]
 MOV  AX,0x01      ???????????
 MOV  [0xF5],BX    ???????????
 MOV  AX,0x00
 MOV  [0xF5],AX
 RET

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM