我已经编写了电影票务系统的代码,并且仅在动作电影1中实现了它来测试其功能。当我运行代码时,一切都很顺利,直到我输入数量。此时,它会显示奇怪的符号,直到付款部分。我应该如何解决这个问题?我使用 emu8086 来运行代码。
.MODEL SMALL
.STACK 100h
.DATA
; for login
username db "testing$" ;set username
password db "1234$" ; set password
welcome_msg db 10,13,"Welcome to City Cineplex Ticketing System!$"
enterName_msg db 10,13,"Please enter your username: $"
enterPwd_msg db 10,13,"Please enter your password: $"
wrong_msg db 10,13,"Invalid username or password. Please try again.$"
correct_msg db 10,13,"Login successful!$"
categories_msg db 10,13,"Please choose a category (1-5): $"
category1 db 10,13,"1. Action$"
category2 db 10,13,"2. Comedy$"
category3 db 10,13,"3. Drama$"
category4 db 10,13,"4. Sci-Fi$"
category5 db 10,13,"5. Horror$"
movies_msg db 10,13,"Please choose a movie(1-5): $"
action_movie1 db 10,13,10,13,"1. Avengers: Startgame - 2hrs 30mins RM15$"
action_movie2 db 10,13,"2. Mission possible - 2hrs 15mins RM13$"
action_movie3 db 10,13,"3. Slow & Calm 100 - 2hrs 20mins RM14$"
action_movie4 db 10,13,"4. John Wick: Chapter 30 - 2hrs 10mins RM12$"
action_movie5 db 10,13,"5. White Panther - 2hrs 15mins RM13$"
comedy_movie1 db 10,13,"1. The Sober - 1hr 45mins RM11$"
comedy_movie2 db 10,13,"2. SuperGood - 1hr 55mins RM12$"
comedy_movie3 db 10,13,"3. Livepool - 2hrs 5mins RM13$"
comedy_movie4 db 10,13,"4. 21 Walk Street - 1hr 50mins RM11$"
comedy_movie5 db 10,13,"5. Teddy - 1hr 45mins RM10$"
drama_movie1 db 10,13,"1. The Shawshank Redemption - 2hrs 22mins RM14$"
drama_movie2 db 10,13,"2. Schindler's List - 3hrs 15mins RM15$"
drama_movie3 db 10,13,"3. Forest Gump - 2hrs 22mins RM14$"
drama_movie4 db 10,13,"4. The Godfather - 2hrs 55mins RM16$"
drama_movie5 db 10,13,"5. The Red Mile - 3hrs 9mins RM15$"
scifi_movie1 db 10,13,"1. Inception - 2hrs 28mins RM15$"
scifi_movie2 db 10,13,"2. Blade Runner 2049 - 2hrs 44mins RM17$"
scifi_movie3 db 10,13,"3. The Matrix - 2hrs 16mins RM14$"
scifi_movie4 db 10,13,"4. Interstellar - 2hrs 49mins RM16$"
scifi_movie5 db 10,13,"5. Moon Wars - 2hrs 1min RM13$"
horror_movie1 db 10,13,"1. The Spiritual Healer - 2hrs 2mins RM12$"
horror_movie2 db 10,13,"2. The Gleaming - 2hrs 26mins RM14$"
horror_movie3 db 10,13,"3. Psychopath - 1hr 49mins RM11$"
horror_movie4 db 10,13,"4. The Summoning - 1hr 52mins RM11$"
horror_movie5 db 10,13,"5. A Daymare on Elm Street - 1 hr 31mins RM10$"
action1_prices db 15
action2_prices db 13
action3_prices db 14
action4_prices db 12
action5_prices db 13
comedy1_prices db 11
comedy2_prices db 12
comedy3_prices db 13
comedy4_prices db 11
comedy5_prices db 10
drama1_prices db 14
drama2_prices db 15
drama3_prices db 14
drama4_prices db 16
drama5_prices db 15
scifi1_prices db 15
scifi2_prices db 17
scifi3_prices db 14
scifi4_prices db 16
scifi5_prices db 13
horror1_prices db 12
horror2_prices db 14
horror3_prices db 11
horror4_prices db 11
horror5_prices db 10
prompt_msg db 10,13,"Enter your choice (1-5): $"
invalid_msg db 10,13,"Invalid choice. Please try again.$"
quantity_msg db 10,13,"Enter the quantity: $"
proceed_msg db 10,13,"Proceed to payment? (Y for Yes/N for No): $"
payment_success_msg db 10,13,"Payment successful!$"
payment_fail_msg db 10,13,"Payment failed. Please try again.$"
menu_msg db 10,13,"Do you want to buy another ticket? (Y/N): $"
goodbye_msg db 10,13,"Thank you for using City Cineplex Ticketing System. Enjoy your movie!$"
beforetax_msg db 10,13,"This is your price before tax: $"
TAX_RATE equ 105
username_buffer db 20, ?
password_buffer db 20, ?
category_selection db ?
movie_selection db ?
quantity db ?
price_before_tax db ?
payment_confirmation db ?
price_after_tax db ?
.CODE
MAIN PROC
MOV AX, @data
MOV DS, AX
; Display welcome message
MOV AH, 09h
LEA DX, welcome_msg
INT 21h
login_prompt:
; Display message asking for username
MOV AH, 09h
LEA DX, enterName_msg
INT 21h
; Read username input
MOV AH, 0Ah
MOV DX, OFFSET username_buffer
INT 21h
; Display message asking for password
MOV AH, 09h
LEA DX, enterPwd_msg
INT 21h
; Read password input
MOV AH, 0Ah
MOV DX, OFFSET password_buffer
INT 21h
; Check if username and password are correct
MOV SI, OFFSET username
MOV DI, OFFSET username_buffer + 2
MOV CX, 7 ; Length of username
CALL compare_strings ; Compare strings
JC login_error ; If not equal, jump to error
MOV SI, OFFSET password
MOV DI, OFFSET password_buffer + 2
MOV CX, 5 ; Length of password
CALL compare_strings ; Compare strings
JC login_error ; If not equal, jump to error
; Username and password are correct, proceed to main menu
MOV AH, 09h
LEA DX, correct_msg
INT 21h
JMP MAIN_MENU
compare_strings:
; Compare strings
@@compare_loop:
LODSB ; Load byte from SI into AL, increment SI
MOV BL, [DI] ; Load byte from DI into BL
CMP AL, BL ; Compare bytes
JNE @@not_equal ; If not equal, jump to not_equal
TEST AL, AL ; Check for end of string
JZ @@equal ; If end of string, strings are equal
INC DI ; Increment DI
LOOP @@compare_loop ; Repeat loop
@@not_equal:
RET ; Return with carry flag set
@@equal:
CLC ; Clear carry flag
RET ; Return
login_error:
; Display error message
MOV AH, 09h
LEA DX, wrong_msg
INT 21h
JMP login_prompt ; Loop back to login prompt
MAIN_MENU:
; Display categories
MOV AH, 09h
LEA DX, category1
INT 21h
LEA DX, category2
INT 21h
LEA DX, category3
INT 21h
LEA DX, category4
INT 21h
LEA DX, category5
INT 21h
; Read category selection
MOV AH, 09h
LEA DX, categories_msg
INT 21h
MOV AH, 01h
INT 21h
SUB AL, '0' ; Convert ASCII to number
CMP AL, 1
JB invalid_category_selection
CMP AL, 5
JA invalid_category_selection
MOV category_selection, AL
; Display movies for the selected category
MOV AH, 09h
CMP category_selection, 1
JE display_action_movies
CMP category_selection, 2
JE display_comedy_movies
CMP category_selection, 3
JE display_drama_movies
CMP category_selection, 4
JE display_scifi_movies
CMP category_selection, 5
JE display_horror_movies
JMP invalid_category_selection
display_action_movies:
MOV AH, 09h
LEA DX, action_movie1
INT 21h
LEA DX, action_movie2
INT 21h
LEA DX, action_movie3
INT 21h
LEA DX, action_movie4
INT 21h
LEA DX, action_movie5
INT 21h
JMP SELECT_ACTION
display_comedy_movies:
MOV AH, 09h
LEA DX, comedy_movie1
INT 21h
LEA DX, comedy_movie2
INT 21h
LEA DX, comedy_movie3
INT 21h
LEA DX, comedy_movie4
INT 21h
LEA DX, comedy_movie5
INT 21h
;JMP SELECT_COMEDY
display_drama_movies:
MOV AH, 09h
LEA DX, drama_movie1
INT 21h
LEA DX, drama_movie2
INT 21h
LEA DX, drama_movie3
INT 21h
LEA DX, drama_movie4
INT 21h
LEA DX, drama_movie5
INT 21h
;JMP SELECT_DRAMA
display_scifi_movies:
MOV AH, 09h
LEA DX, scifi_movie1
INT 21h
LEA DX, scifi_movie2
INT 21h
LEA DX, scifi_movie3
INT 21h
LEA DX, scifi_movie4
INT 21h
LEA DX, scifi_movie5
INT 21h
;JMP SELECT_SCIFI
display_horror_movies:
MOV AH, 09h
LEA DX, horror_movie1
INT 21h
LEA DX, horror_movie2
INT 21h
LEA DX, horror_movie3
INT 21h
LEA DX, horror_movie4
INT 21h
LEA DX, horror_movie5
INT 21h
;JMP SELECT_HORROR
invalid_category_selection:
; Display error message
MOV AH, 09h
LEA DX, invalid_msg
INT 21h
JMP MAIN_MENU ; Loop back to main menu
SELECT_ACTION:
MOV AH,09h
LEA DX,movies_msg
INT 21h
MOV AH,01h
INT 21h
SUB AL, '0'
CMP AL,1
JB invalid_action_selection
CMP AL,5
JA invalid_action_selection
MOV movie_selection, AL
MOV AH,09h
CMP movie_selection, 1
JE action1
; CMP movie_selection, 2
;JE action2
; CMP movie_selection, 3
;JE action3
; CMP movie_selection, 4
;JE action4
; CMP movie_selection, 5
; JE action5
JMP invalid_category_selection
action1:
; Display prompt for quantity
MOV AH, 09h
LEA DX, quantity_msg
INT 21h
; Read quantity input
MOV AH, 01h
INT 21h
SUB AL, '0' ; Convert ASCII to number
MOV quantity, AL
; Multiply action1_prices with quantity
INDEC3 PROC ;INDEC3 IS FOR TAKING INPUT FOR MULTIPLY WITH THE GIVEN AMOUNT
PUSH BX ;TAKE VALUES INTO STACK
PUSH CX
PUSH DX
XOR BX,BX ;HOLDS TOTAL
XOR CX,CX ;SIGN
MOV AH,1 ;TAKE CHARACTER IN AL
INT 21H
REPEAT4:
CMP AL,48 ;IF AL<0, PRINT ERROR MESSAGE
JL invalid_action_selection
CMP AL,57 ;IF AL>9, PRINT ERRIR MESSAGE
JG invalid_action_selection
AND AX,00FH ;CONVERT TO DIGIT
PUSH AX ;SAVE ON STACK
MOV AX,10 ;GET 10
MUL BX ;AX=TOTAL * 10
POP BX ;GET DIGIT BACK
ADD BX,AX ;TOTAL = TOTAL X 10 +DIGIT
MOV AH,1
INT 21H
CMP AL,0DH ;CARRIAGE RETURN
JNE REPEAT4 ;IF NO CARRIEGE RETURN THEN MOVE ON
MOV AX,BX ;STORE IN AX
;AND RETURN
; Display price before tax
MOV AH, 09h
LEA DX, beforetax_msg
INT 21h
; Display the calculated price
MOV AH, 09h
LEA DX, price_before_tax
INT 21h
; Continue with payment confirmation
JMP PAYCONFIRMATION
invalid_action_selection:
; Display error message
MOV AH, 09h
LEA DX, invalid_msg
INT 21h
JMP display_action_movies ; Loop back selection of action movies
PAYCONFIRMATION:
; Display payment confirmation message
MOV AH, 09h
LEA DX, proceed_msg
INT 21h
; Read payment confirmation
MOV AH, 01h
INT 21h
CMP AL, 'Y'
JNE not_proceed_payment
; Calculate price after tax
MOV Ah, price_before_tax
MOV Bh, TAX_RATE
MUL Bh
MOV Bh, 100
DIV BH
MOV price_after_tax, AL
; Display price after tax
MOV AH, 09h ; Display function
MOV DL, '$'
INT 21h
MOV AH, price_after_tax
; Display payment success message
MOV AH, 09h
LEA DX, payment_success_msg
INT 21h
; Prompt for another ticket purchase
MOV AH, 09h
LEA DX, menu_msg
INT 21h
; Read menu choice
MOV AH, 01h
INT 21h
CMP AL, 'Y'
JNE exit_program
; Loop back to main menu
JMP MAIN_MENU
not_proceed_payment:
; Display goodbye message and exit
MOV AH, 09h
LEA DX, goodbye_msg
INT 21h
JMP exit_program
exit_program:
; Exit program
MOV AH, 4Ch
INT 21h
ascii_to_num:
XOR AL, AL ; Clear AL to store result
@@convert_loop:
MOV AH, 0 ; Clear AH for DIV operation
LODSB ; Load character into AL, increment SI
CMP AL, 0DH ; Check for Enter key
JE @@done ; If Enter, done converting
SUB AL, '0' ; Convert ASCII character to numerical value
CMP AL, 0 ; Check for valid digit (0-9)
JB @@error ; If not a valid digit, exit with AL = 0
CMP AL, 9 ; Check if digit is greater than 9
JA @@error
; Multiply AL by 10 and add the current digit
MOV BL, 10
MUL BL
ADD AL, AH
JMP @@convert_loop
@@error:
XOR AL, AL ; Set AL = 0 to indicate error
RET
@@done:
RET
END MAIN
系统流程应该是用户输入类别,它会列出所选类别中的所有电影。之后,用户需要选择电影并输入数量。系统应显示税前价格。然后系统应该询问用户是否继续付款。如果没有,请跳回电影选择。如果是,则显示加5%服务税后的价格。然后用户需要去付款部分。
问题:
09h
服务打印整数(字节)。
错误:
第 201 行 - 相对跳转超出范围 003Ah 字节
第 203 行 - 相对跳转超出范围 0036h 字节
使用说明
`JB invalid_category_selection`
`JA invalid_category_selection`
产生错误,因为
invalid_category_selection
距离当前IP太远。
JA rel8 Jump short if above (CF=0 and ZF=0)
JB rel8 Jump short if below (CF=1)
短跳转 — 近跳转,跳转范围限制为当前 IP 值的 –128 至 +127。
我放置了另一个标签
invalid_category_selection_in_range
下面几行以及从那里的说明
jmp invalid_category_selection
跳转至 invalid_category_selection
。
JB invalid_category_selection_in_range
CMP AL, 5
JA invalid_category_selection_in_range
MOV category_selection, AL
; Display movies for the selected category
MOV AH, 09h
CMP category_selection, 1
JE display_action_movies
CMP category_selection, 2
JE display_comedy_movies
CMP category_selection, 3
JE display_drama_movies
CMP category_selection, 4
JE display_scifi_movies
CMP category_selection, 5
JE display_horror_movies
JMP invalid_category_selection
invalid_category_selection_in_range:
jmp invalid_category_selection
警告:
第 491 行 - 打开程序:INDEC3 第 491 行 - 打开程序:MAIN
; Line 341
INDEC3 PROC ;INDEC3 IS FOR TAKING INPUT FOR MULTIPLY WITH THE GIVEN AMOUNT
这条线就在那里。我没看到
INDEC3 ENDP
。所以我把它注释掉了。
; Line 492
END MAIN
MAIN PROC
已打开但未关闭。
MAIN ENDP
END MAIN
好的,现在汇编器安静了。 :) 但代码无法正常工作。
Enter the quantity: 23
˛ ˛ ĺ ☼░ä↨˛ ˛ Ü É╚ ˛ ░ś Ü ĺ ĺ
ĺ @î ĺ ë ♥ ĺÇ ĺ ĺ ĺ ĺ ░ś ˛ ☺☺áâ↨ĺ
☼ ↨˛ ¨♂░ö↨â ¨♂░ö↨ĺ ♥░á↨é ♥░á↨˛
Proceed to payment? (Y for Yes/N for No):
嗯,
Enter the quantity
部分看起来不错。
但是这里,
09h
服务用于打印字符串,price_before_tax
是整数(字节)。
因此,将此整数除以 10,打印余数,如果商大于 0,则重复。
; Display the calculated price
MOV AH, 09h
LEA DX, price_before_tax
INT 21h
; Continue with payment confirmation
JMP PAYCONFIRMATION