DOSBox 0.74汇编报错(67)Relative jump out of range的解决求助
问题分析与修复方案
错误原因
报错"(67)Relative leap out of range by 0028h bytes"是因为你使用的jne C1是8位短跳转指令,它只能跳转±127字节范围内的地址。而你的代码中,jne指令到C1标签之间的代码长度超过了127字节,超出了短跳转的范围,因此汇编器报错。
修复步骤
1. 替换短跳转为近跳转
把jne C1修改为jne NEAR PTR C1,近跳转(16位)支持整个代码段内的跳转(范围±32767字节),完全覆盖你的代码长度。
2. 修复未初始化变量的问题
代码开头显示总价时,tempTotal未初始化,会输出随机值。需要在初始化数据段后,先把totalPrice的值赋给tempTotal:
MOV AX, @DATA MOV DS, AX ; 新增初始化tempTotal MOV AL, totalPrice MOV tempTotal, AL
3. 删除多余的输出指令
计算完tempRebate、tempTotal后有几处多余的MOV AH, 02H+INT 21H,会输出随机ASCII字符,直接删除这些冗余指令。
修改后的完整代码
TITLE TOTAL_PAYMENT ; TITLE directive .MODEL SMALL ; .STACK 64 ; .DATA checkOut DB 10, 13, 'Total Check out: RM$' ; total DB 10, 13, 'Total Price: RM $' ; rebate DB 10, 13, 'Discount: RM $' ; membership DB 10, 13, 'Membership(yes = y): $' ; SST DB 10, 13, 'SST: RM $' ; totalPrice DB 30 ; divide DB 100 mulSST DB 5 mulDiscount DB 10 temp DB ? ; remainderR DB ? ; remainderD DB ? ; tempRebate DB ? ; tempSST DB ? ; tempTotal DB ? ; ;-------------------------------------------------------------------------------------------------------------------- .CODE MAIN PROC FAR ; MOV AX, @DATA ; MOV DS, AX ; ; 初始化tempTotal为totalPrice的初始值 MOV AL, totalPrice MOV tempTotal, AL MOV AH, 09H ; let user to input if the user is membership or not LEA DX, membership ; INT 21H ; MOV AH, 01H ; INT 21H ; MOV temp, AL ; MOV AH, 02H ;new line MOV DL, 0DH INT 21H MOV DL, 0AH INT 21H MOV AH, 09H ; LEA DX, total ; display total INT 21H; ; MOV AL, tempTotal ; AAM ADD AX, 3030H ; PUSH AX ; MOV DL, AH ; MOV AH, 02H ; INT 21H POP DX ; MOV AH, 02H ; INT 21H MOV AH, 02H ;new line MOV DL, 0DH INT 21H MOV DL, 0AH INT 21H CMP temp, 79H ; if isMember get discount, else no discount jne NEAR PTR C1 ; 修改为近跳转,解决范围问题 MOV AH, 09H ; LEA DX, rebate ; display rebate message INT 21H ; MOV AL, totalPrice ; MUL mulDiscount ; DIV divide ; MOV tempRebate, AL ; ; 删除多余的输出指令 ; MOV AH, 02H ; INT 21H ; MOV AL, tempRebate ; AAM ADD AX, 3030H ; PUSH AX ; MOV DL, AH ; MOV AH, 02H ; INT 21H POP DX ; MOV AH, 02H ; INT 21H MOV AH, 02H ;new line MOV DL, 0DH INT 21H MOV DL, 0AH INT 21H MOV AH, 09H ; LEA DX, SST ; display sst INT 21H; ; MOV AL, totalPrice ; MUL mulSST ; DIV divide ; MOV tempSST, AL ; MOV AL, tempSST ; AAM ADD AX, 3030H ; PUSH AX ; MOV DL, AH ; MOV AH, 02H ; INT 21H POP DX ; MOV AH, 02H ; INT 21H MOV AH, 02H ;new line MOV DL, 0DH INT 21H MOV DL, 0AH INT 21H MOV AH, 09H ; LEA DX, checkOut ; display checkOut INT 21H ; MOV AL, totalPrice ; MOV BL, tempRebate ; SUB AL, BL ; MOV tempTotal, AL ; MOV AL, tempTotal ; MOV BL, tempSST ; ADD AL, BL ; MOV tempTotal, AL ; ; 删除多余的输出指令 ; MOV AH, 02H ; INT 21H ; MOV AL, tempTotal ; AAM ADD AX, 3030H ; PUSH AX ; MOV DL, AH ; MOV AH, 02H ; INT 21H POP DX ; MOV AH, 02H ; INT 21H JMP endCode ;-------------------------------------------------------------------------------------------------------------------- C1: MOV AH, 09H ; LEA DX, SST ; display sst INT 21H; ; MOV AL, totalPrice MUL mulSST DIV divide MOV tempSST, AL MOV AL, tempSST ; AAM ADD AX, 3030H ; PUSH AX ; MOV DL, AH ; MOV AH, 02H ; INT 21H POP DX ; MOV AH, 02H ; INT 21H MOV AH, 02H ;new line MOV DL, 0DH INT 21H MOV DL, 0AH INT 21H MOV AH, 09H ; LEA DX, checkOut ; display checkOut INT 21H ; MOV AL, totalPrice MOV BL, tempSST ADD AL, BL MOV tempTotal, AL ; 删除多余的输出指令 ; MOV AH, 02H ; INT 21H ; MOV AL, tempTotal ; AAM ADD AX, 3030H ; PUSH AX ; MOV DL, AH ; MOV AH, 02H ; INT 21H POP DX ; MOV AH, 02H ; INT 21H endCode: MOV AX, 4C00H ; INT 21H ; MAIN ENDP ; END MAIN ;
额外说明
修改后不仅解决了跳转范围的报错,还修正了初始总价显示随机值、多余输出随机字符的问题,代码逻辑更完整。
内容的提问来源于stack exchange,提问作者Laoshen老绅
相关产品推荐
相关产品推荐

