如何修复汇编语言中的跳转目标错误?

时间:2014-03-15 00:34:20

标签: assembly masm irvine32

我正在构建一个简单的程序来计算每加仑的女孩,英里和里程取决于用户输入的内容。我正在做的是创建一个菜单,它将有4个任务。用户将输入分配给每个任务的字符。例如,如果用户输入M,它将计算实际的mpg。如果他/她进入D,它将计算距离,依此类推。程序将循环回到菜单,直到用户键入Q.但是,当我到达任务2时,我得到编译器错误,它说,跳转目标太远了....现在我不知道有一个跳跃条件的范围。我使用大多数cmp和je指令进行记录。这是我的问题,有没有办法解决跳转目标错误?我该怎么做?任何帮助,将不胜感激。感谢

TITLE test.asm

INCLUDE Irvine32.inc

.data
menuString BYTE "M - Calculate the actual miles per Gallon or MPG", 0ah, 0dh
         BYTE "D - Calculate the max distance you can travel", 0ah, 0dh
         BYTE "G - Calculate the gas required for a trip", 0ah, 0dh
         BYTE "Q - Quit the program", 0ah, 0dh
         BYTE "Choose M, D, G, Q with the following option: ", 0

newLine BYTE "t ", 0ah, 0dh, 0

galsString BYTE "Gals: ", 0
milesString BYTE "Miles: ", 0
mpgString BYTE "MPG: ", 0

choice BYTE ?

gals DWORD ?
miles DWORD ?
mpg DWORD ?

.code
main PROC

Menu:
    mov edx, OFFSET menuString
    call WriteString                ; display the menu
    call ReadChar                   ; read the user input choice
    mov choice, al                  ; move the choice to AL register
    call WriteChar                  ; display the charater choice to screen
    cmp al, 4dh                 ; compare character choice to M = 4d in hex
    je M                        ; if equal, jump to M

    cmp al, 44h                 ; compare character choice to Q
    je D                        ; if equal, jump to D

    cmp al, 51h                 ; compare character choice to Q
    je Q                        ; if equal, jump to Q

    ;dividend ÷ divisor = quotient
    ;(eax) 32 bit

    M:
        mov edx, OFFSET newLine     ;
        mov edx, OFFSET milesString ; ask the user to input miles
        call WriteString        ; display miles to the screen

        call ReadDec            ; read the miles input and store to EAX register
        mov miles, eax          ; assign miles equal to EAX

        mov edx, OFFSET galsString  ; ask the user to input gals
        call WriteString        ; display gals to the screen

        mov edx , 0         ; set edx = 0, prepare for the divison

        call ReadDec            ; read the gals input and store to EAX register
        mov gals, eax           ; assign gals equal to EAX

        mov eax, miles          ; assign miles equal to EAX, make it a divident

        div gals            ; gals will be divisor  
        call WriteDec           ; write the result to screen
        loop Menu           ; go back to the menu

        D:
        mov edx, OFFSET mpgString
        call WriteString

        call ReadDec
        mov mpg, eax

        mov edx, OFFSET galsString
        call WriteString

        ;mov edx, 0

        call ReadDec
        mov gals, eax

        mov edx, mpg

        mul ecx
        call WriteDec
        loop Menu
    Q:
        exit

main ENDP
END main

2 个答案:

答案 0 :(得分:0)

如果汇编程序不够聪明,无法自行解决,请使用显式跳转大小覆盖。这可能类似je nearje near ptr或类似内容。

答案 1 :(得分:-1)

使用相对跳跃时有一个限制,所以你可以像这样使用绝对跳跃:

mov eax,your_destination
jmp eax

对于您的示例,如果不满足条件,则需要使用负逻辑跳过绝对跳转。例如:

cmp al, 4dh                 ; compare character choice to M = 4d in hex
jne NOT_M
mov eax, M
jmp eax
NOT_M:

cmp al, 44h                 ; compare character choice to Q
jne NOT_D       
mov eax, D
jmp eax
NOT_D:

cmp al, 51h                 ; compare character choice to Q
jne NOT_Q      
mov eax, Q
jmp eax
NOT_Q: