调用汇编语言中的函数时出现问题,不起作用。

huangapple go评论54阅读模式
英文:

Call not working properly to call function in assembly

问题

我是你的中文翻译,以下是你要翻译的代码部分:

.model small
.stack 150h
.data
Menu db 10, 13, 'Enter a choice (1 to 2):'
db 10, 13, '1) Enter 1 to view activites'
db 10, 13, '2) Enter 2 to view workshop'
db 10, 13, '3) Enter 3 to view competition'
db 10, 13, '4) Reset value', 10, 13, '$'

msg db 10,13, "activities $10"
msg2 db 10,13, "workshop $15"
msg3 db 10,13, "view competition $20"
Fdigit db 0
Sdigit db 0

result db 10,13,"sum= : $"
afd db '1'
asd db '0'
wfd db '1'
wsd db '5'
cfd db '2'
csd db '0'

.code

Main proc

mov ax,@data
mov ds,ax

DisplayMenu:
mov dx,OFFSET Menu
mov ah,9
int 21h
mov ah,1
int 21h

cmp al, '1'
je view_activites 
cmp al, '2'
je view_workshop
cmp al, '3' 
call view_comp
cmp al, '4'
call reset 

view_activites:
; 查看活动的代码
mov ah,09h
mov dx,offset msg
int 21h

mov bl,Sdigit 
sub bl,30h
mov cl,asd

add bl,cl

mov al,bl
mov ah,00h
aaa

mov cl,al
mov bl,ah

mov bh,Fdigit
sub bh,30h
mov ch,afd

add bl,bh
add bl,ch

mov al,bl
mov ah,00h
aaa

mov bx,ax

mov dx, offset result
mov ah,09h
int 21h

; 第一位数字
mov Fdigit,bl
mov dl,Fdigit
add dl,30h
mov ah,02h
int 21h

; 第二位数字
mov Sdigit,cl
mov dl,Sdigit
add dl,30h
mov ah,02h
int 21h
jmp DisplayMenu
ret

view_workshop:
; 查看研讨会的代码
mov ah,09h
mov dx,offset msg2
int 21h

mov bl,Sdigit
sub bl,30h
mov cl,wsd

add bl,cl

mov al,bl
mov ah,00h
aaa

mov cl,al
mov bl,ah

mov bh,Fdigit
sub bh,30h
mov ch,wfd

add bl,bh
add bl,ch

mov al,bl
mov ah,00h
aaa
mov bx,ax

; 第一位数字
mov Fdigit,bl
mov dl,Fdigit
add dl,30h
mov ah,02h
int 21h

; 第二位数字
mov Sdigit,cl
mov dl,Sdigit
add dl,30h
mov ah,02h
int 21h
jmp DisplayMenu
ret

view_comp:
mov ah,09h
mov dx,offset msg
int 21h

mov bl,Sdigit 
sub bl,30h
mov cl,csd

add bl,cl

mov al,bl
mov ah,00h
aaa

mov cl,al
mov bl,ah

mov bh,Fdigit
sub bh,30h
mov ch,cfd

add bl,bh
add bl,ch

mov al,bl
mov ah,00h
aaa

mov bx,ax

mov dx, offset result
mov ah,09h
int 21h

; 第一位数字
mov Fdigit,bl
mov dl,Fdigit
add dl,30h
mov ah,02h
int 21h

; 第二位数字
mov Sdigit,cl
mov dl,Sdigit
add dl,30h
mov ah,02h
int 21h

jmp DisplayMenu
ret

reset:
mov Fdigit,0
mov Sdigit,0

mov dx, offset result
mov ah,09h
int 21h

; 第一位数字
mov Fdigit,0
mov dl,Fdigit
mov ah,02h
int 21h

; 第二位数字
mov Sdigit,0
mov dl,Sdigit
mov ah,02h
int 21h

jmp DisplayMenu
ret

quit_program:
mov ah,09h
mov dx,offset Fdigit
int 21h
mov ah,4ch
int 21h

Main endp
End main

希望这可以帮助你解决问题。

英文:

Im kinda new to assembly, so im trying to create a ticket buying system which has 4 function. User can enter 1 to 4 to select the function but when i enter 4 to the run reset function it run view_comp function (which is the 3rd function). The other 3 function works properly but only 4th function has problem

.model small
.stack 150h
.data
Menu db 10, 13, 'Enter a choice (1 to 2):'
db 10, 13, '1) Enter 1 to view activites'
db 10, 13, '2) Enter 2 to view workshop'
db 10, 13, '3) Enter 3 to view competition'
db 10, 13, '4) Reset value', 10, 13, '$'


msg db 10,13, "activities $10"
msg2 db 10,13, "workshop $15"
msg3 db 10,13, "view competition $20"
Fdigit db 0
Sdigit db 0

result db 10,13,"sum= : $"
afd db '1'
asd db '0'
wfd db '1'
wsd db '5'
cfd db '2'
csd db '0'


.code

Main proc


mov ax,@data
mov ds,ax

DisplayMenu:
mov dx,OFFSET Menu
mov ah,9
int 21h
mov ah,1
int 21h


cmp al, '1'
je view_activites 
cmp al, '2'
je view_workshop
cmp al, '3' 
call view_comp
cmp al, '4'
call reset 



view_activites:
; code to view activites
mov ah,09h
mov dx,offset msg
int 21h

mov bl,Sdigit 
sub bl,30h
mov cl,asd

add bl,cl

mov al,bl
mov ah,00h
aaa

mov cl,al
mov bl,ah


mov bh,Fdigit
sub bh,30h
mov ch,afd

add bl,bh
add bl,ch

mov al,bl
mov ah,00h
aaa

mov bx,ax
;mov bh, ah
;mov bl,al

mov dx, offset result
mov ah,09h
int 21h

;1st digit
mov Fdigit,bl
mov dl,Fdigit
add dl,30h
mov ah,02h
int 21h

;2nd digit
mov Sdigit,cl
mov dl,Sdigit
add dl,30h
mov ah,02h
int 21h
jmp DisplayMenu
ret



view_workshop:
; code to view workshop
mov ah,09h
mov dx,offset msg2
int 21h

mov bl,Sdigit
sub bl,30h
mov cl,wsd

add bl,cl

mov al,bl
mov ah,00h
aaa

mov cl,al
mov bl,ah

mov bh,Fdigit
sub bh,30h
mov ch,wfd

add bl,bh
add bl,ch

mov al,bl
mov ah,00h
aaa
mov bx,ax

;1st digit
mov Fdigit,bl
mov dl,Fdigit
add dl,30h
mov ah,02h
int 21h

;2nd digit
mov Sdigit,cl
mov dl,Sdigit
add dl,30h
mov ah,02h
int 21h
jmp DisplayMenu
ret


view_comp:
mov ah,09h
mov dx,offset msg
int 21h

mov bl,Sdigit 
sub bl,30h
mov cl,csd

add bl,cl

mov al,bl
mov ah,00h
aaa

mov cl,al
mov bl,ah


mov bh,Fdigit
sub bh,30h
mov ch,cfd

add bl,bh
add bl,ch

mov al,bl
mov ah,00h
aaa

mov bx,ax
;mov bh, ah
;mov bl,al

mov dx, offset result
mov ah,09h
int 21h

;1st digit
mov Fdigit,bl
mov dl,Fdigit
add dl,30h
mov ah,02h
int 21h


;2nd digit
mov Sdigit,cl
mov dl,Sdigit
add dl,30h
mov ah,02h
int 21h

jmp DisplayMenu
ret

reset:


    mov Fdigit,0
    mov Sdigit,0
    
mov dx, offset result
mov ah,09h
int 21h
    
    ;1st digit
mov Fdigit,0
mov dl,Fdigit
mov ah,02h
int 21h


;2nd digit
mov Sdigit,0
mov dl,Sdigit
mov ah,02h
int 21h
    
jmp DisplayMenu

ret



quit_program:
mov ah,09h
mov dx,offset Fdigit
int 21h
mov ah,4ch
int 21h

Main endp
End main

What i expect the code above to work properly but now i dont have any idea how to solve this issue.

答案1

得分: 2

A cmp单独并不足以改变程序的执行路径。前两个是正确的,但后两个将不受上面比较结果的影响而执行。虽然CPU已经比较了al和3,但它并没有基于比较结果执行任何操作。从本质上讲,cmp al, '3'flags寄存器受到影响方面与sub al, '3'相同,但al的内容保持不变。对于前两种情况,你已经使用了je来基于flags进行分支。正如PeterCordes所解释的,你实际上可以通过重新排列代码来减少分支来优化这个过程。可能有比我在这里展示的更好的方法,但这只是一个例子。(根据每个标签下有多少代码,你可能会超过je的距离限制,所以要记住这一点。)

cmp al, '1'
je 查看活动
cmp al, '2'
je 查看研讨会
cmp al, '3'
je 查看竞赛

; 否则,重置

重置:
    mov Fdigit, 0
    mov Sdigit, 0
    ; 重置代码的其余部分在这里
    jmp 显示菜单

查看活动:
    ; 在这里放置你的代码
    jmp 显示菜单

查看研讨会:
    ; 在这里放置你的代码
    jmp 显示菜单

查看竞赛:
    ; 在这里放置你的代码
    jmp 显示菜单

退出程序:
    ; 在这里放置你的代码
英文:

A cmp by itself isn't enough to change the execution path of the program. The first two are correct, but the second two will execute regardless of the result of the compare above them. While the CPU has compared al to 3, it hasn't done anything based on the result of that comparison. Essentially, cmp al, '3' is the same as sub al, '3' in terms of how the flags register is affected, but the contents of al remain unchanged. For the first two cases, you've used je to branch based on the flags. As PeterCordes explained, you can actually optimize this a bit by rearranging your code to reduce branching. There's probably a better way than I've shown here, but it's just one example. (Depending on how much code you have under each label you might exceed the distance limit on je so keep that in mind.)

cmp al, '1'
je view_activites 
cmp al, '2'
je view_workshop
cmp al, '3' 
je view_comp

;else, reset

reset:
    mov Fdigit,0
    mov Sdigit,0
    ;rest of reset code goes here
    jmp DisplayMenu

view_activities:
    ; put your code here
    jmp DisplayMenu

view_workshop:
    ; put your code here
    jmp DisplayMenu

view_comp:
    ; put your code here
    jmp DisplayMenu

quit_program:
    ; put your code here

huangapple
  • 本文由 发表于 2023年2月9日 03:20:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75390744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定