| |

VerySource

 Forgot password?
 Register
Search
View: 719|Reply: 2

Why is the program in Wang Shuang's compilation showing garbled characters?

[Copy link]

2

Threads

4

Posts

5.00

Credits

Newbie

Rank: 1

Credits
5.00

 China

Post time: 2020-1-3 15:00:01
| Show all posts |Read mode
The following program is the curriculum design in Wang Shuang's compilation. I wrote it n times and changed it for several days, but it always failed to achieve the desired result. May I ask which master is wrong?

Program tasks:
Display the following data on the screen
Year Annual total income Number of employees Per capita income
1975 16 3?
1976 22 7?
1977 382 9?
1978 1356 13?
1979 2390 28?
1980 8000 38?
1981 16000 130?
1982 24486 220?
1983 50065 476?
1984 97479 778?
1985 140417 1001?
1986 197514 1442?
1987 345980 2258?
1988 590827 2793?
1989 803530 4037?
1990 1183000 5635?
1991 1843000 8226?
1992 2759000 11542?
1993 3753000 14430?
1994 4649000 15257?
1995 5937000 17800?


program:
assume cs: code
data segment
     db '1975', '1976', '1977', '1978', '1979', '1980', '1981', '1982'
     db '1983', '1984', '1985', '1986', '1987', '1988', '1989', '1990'
     db '1991', '1992', '1993', '1994', '1995', 0
     The above are 21 strings representing 21 years
     dd 16,22,382,1356,2390,8000,16000,24486
     dd 50065,97479,140417,197514,345980,590827,803530,1183000
     dd 1843000,2759000,3753000,4649000,5937000
     The above is 21 dword-type data representing the company's total revenue in 21 years
     dw 3,7,9,13,28,38,130,220
     dw 476,778,1001,1442,2258,2793,4037,5635
     dw 8226,11542,14430,15257,17800
     The above is 21 word data representing the number of employees in the company for 21 years
data ends
tempdata segment
     db 8 dup (0)
tempdata ends
code segment
start: mov ax, data
     mov ds, ax; send data segment address to ds
     mov ax, 0b800h
     mov es, ax; send the video memory base address to es
     sub cx, cx; clear cx to 0
     mov bx, 0; point the data segment data offset address to data: 0
     mov di, 0; point the memory offset to b800: 0
     mov si, 0; employee address offset
throwout: mov cl, ds: [bx]
         jcxz finished; Check whether the data is displayed, if it is finished
         mov dl, 02h
         mov al, ds: [bx]
         mov es: [di], al
         mov es: [di + 1], dl; send the first character of the year field to the video memory es: [di]
         mov al, ds: [bx + 1]
         mov es: [di + 2], al
         mov es: [di + 3], dl; send the second character of the year field to the video memory es: [di + 2]
         mov al, ds: [bx + 2]
         mov es: [di + 4], al
         mov es: [di + 5], dl; send the third character of the year field to the video memory es: [di + 4]
         mov al, ds: [bx + 3]
         mov es: [di + 6], al
         mov es: [di + 7], dl; send the fourth character of the year field to the video memory es: [di + 6]
         mov ax, ds: [bx + 55h]
         mov dx, ds: [bx + 57h]; send the total income field dd to the register dx (higher 16 bits), ax (lower 16 bits)
         mov bp, 32; point offset address to first cell address in total revenue field
         call dtoc; call the subroutine dtoc, and send the total revenue field to the video memory es: [sp + di]
         mov ax, ds: [si + 0a9h]
         mov dx, 0; send employee field dw to register ax
         call getbp; call the subroutine getbp to calculate the starting address of the employee field of each record in the video memory
         call dtoc; call subroutine dtoc, send employee field to video memory es: [sp + di]
         mov ax, ds: [bx + 55h]
         mov dx, ds: [bx + 57h]
         mov cx, bx
         mov bx, ds: [si + 0a9h]; send the total income field dd to the register dx (high 16 bits), ax (low 16 bits), and send the employee field dw to the register bx
         call divdw; call subroutine divdw, calculate the value of per capita income
         mov bx, cx
         mov cx, 0
         call getbp; call the subroutine getbp to calculate the starting address of the per capita income field of each record in the video memory
         call dtoc; call subroutine dtoc, and send the per capita income field to video memory es: [sp + di]
         add bx, 4
         add si, 2
         add di, 160; the above 3 sentences are prepared for storing data in the next cycle
         jmp throwout; if the data is not displayed, jump to throwout to enter the next cycle
finished: mov ax, 4c00h; After the data is displayed, dos is returned.
         int 21h
; The following is the subroutine dtoc, function: convert digital data into characters and send it to video memory; parameters: dd data (transmitted by ax, dx), the offset bp, di of each record in video memory Returns: the offset bp of each record in video memory, preparing for the next field
dtoc: push si
     push ds
     push bx
     push cx
     mov si, 0
     mov bx, tempdata
     mov ds, bx
   s: mov cx, ax
     jcxz ok
     mov bx, 0ah
     call divdw
     add cl, 30h
     mov ds: [si], cl
     inc si
     jmp s
  ok: mov bh, 02h
     mov cx, si
   a: mov bl, ds: [si]
     mov es: [bp + di], bl
     mov es: [bp + di + 1], bh
     sub si, 1
     add bp, 2
     loop a
     pop cx
     pop bx
     pop ds
     pop si
     ret
The following is the subroutine divdw, which calculates the quotient and remainder of two values
divdw: push si; ax, dx, bx ax, dx, cx
      push ax
      mov ax, dx
      mov dx, 0
      div bx
      mov si, ax
      pop ax
      div bx
      mov cx, dx
      mov dx, si
      pop si
      ret
The following is the value of the subroutine getbp, offset bp
getbp: push ax; bp bp
      push bx
      mov ax, bp
      mov bx, 0
      mov bl, 32
      div bl
      sub bl, ah
      add bp, bx
      pop bx
      pop ax
      ret
code ends
end start
Reply

Use magic Report

0

Threads

23

Posts

17.00

Credits

Newbie

Rank: 1

Credits
17.00

 China

Post time: 2020-1-4 03:06:01
| Show all posts
There are roughly two problems. The first is in the throwout: loop, when calculating the average value, bx is saved through cx, but the divdw subroutine uses cx, so the value of cx has changed. This Save invalidation. "Save-Restore" can be done through the stack:
...
         mov dx, ds: [bx + 57h]
         push bx; * mov cx, bx push here to save bx
         mov bx, ds: [si + 0a9h]; the total revenue field ....
         call divdw; call subroutine divdw, calculate the value of per capita income
         pop bx; * mov bx, cx
         mov cx, 0
...

The second problem is that in the dtoc subroutine, the final result is that si points to the end of the valid string. For example, the first value is 16, the converted string is "61", and si does not point to '1' It's the next byte of '1'. So si should be subtracted by 1:
...
  ok: mov bh, 02h
     mov cx, si
     dec si; * + here!
   a: mov bl, ds: [si]
...
Reply

Use magic Report

2

Threads

4

Posts

5.00

Credits

Newbie

Rank: 1

Credits
5.00

 China

 Author| Post time: 2020-2-3 19:30:01
| Show all posts
Thankswww_jamesfor pointing
Reply

Use magic Report

You have to log in before you can reply Login | Register

Points Rules

Contact us|Archive|Mobile|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

Quick Reply To Top Return to the list