【问题标题】:Assembly x86 | return(ret) is not working组装 x86 |返回(ret)不起作用
【发布时间】:2020-04-15 11:58:28
【问题描述】:

嗯,最近我开始学习 Assembly 8086 主要是出于好奇。

汇编中的输入只允许你输入一个字符,所以我尝试在汇编8086中制作一个程序,允许你输入多位整数输入,以“空格”结束输入(' '),然后添加数字并打印值。

我看到 pushpop 可用于将参数传递给过程,但我尝试使用它们使我的过程返回一些内容并将其存储到变量中,我无法想象一种方法这与ret 基于我对Assembly 8086 的了解,所以......无论如何,我做了一个程序,但由于某种原因,程序末尾的ret 似乎不起作用,并且程序运行无限次。

目前的代码:

.model small
org 100h

.data

    fv db 0 ;variables to store the numbers
    sv db 0 ;

.code
    jmp start ;a pattern of mine in some way to avoid a procedure be called twice and what everyone shows 
              ;just doesn't work, after the main ends, all the procs run again,
              ;it worked perfectly any other time I used procedures to my program

    f1 proc   ;the procedure

        mov cl, 0 ;clear cl bcs later the first time is used I have not stored some thing in there and 
                  ;always for some reason, to all my programs "cx" has a value stored, maybe from the
                  ;emulator I use

        mov ah, 1h ;single character input
        int 21h    ;

        while:
            cmp al, ' ' ;if input is equal to "space"("space" must be the last input, as far as I have
                        ;gone with the program)
            jne true    ; if input != ' '
            je false    ; if input == ' '
            true:       ; in case input != ' '
                mov bl, al ;store the input
                mov al, cl ;digits taken from input previously
                sub bl, 30h;bcs if input == 8, whatactually is stored is the ASCII code of it in this
                           ;case : 38h or 56

                mov dl, 10 ;What I thought : if user writes as input 12, what actually types 1 * 10 + 2
                           ;so I am storing 10 to dl to multiply the previously entered numbers in the
                           ;example above : 1

                mul dl     ;multiplication

                add al, bl ;add new input to (old inputs * 10)

                mov cl, al ;store old inputs

                mov ah, 1h ;input
                int 21h    ;
                jmp while  ;check again if input == ' ' or not
        false: ;in case input == ' '
            mov ch, 0 ; in chase ch had some thing else in it from something else than the
                      ; input(0 <= input <= 127~128(127 + 128 = 255))
            push cx   ; store cx(final result from the inputs) in to the stack to store it to a 
                      ; variable

            ret       ; end procedure
    f1 endp           ; 

    start:            ; with "jmp start" at the start of the ".code" makes the program start from "main"
    main proc

        call f1    ;call procedure
        pop bx     ;store result in to bx bcs `push` and `pop` as far as I know need at least 16-bit
                   ;and varables are 8-bit, I know I can make them 16-bit but anyway
        mov fv, bl ;store result to variable   

    endp
end main

【问题讨论】:

  • 通过寄存器而不是堆栈更好地传递值。
  • @Mike 我也猜到了,但我只是想“玩”一下筹码,给自己一些挑战

标签: assembly x86 emu8086


【解决方案1】:

好吧,我找到了它,在我将其他任何东西推入堆栈之前(我搜索了 pushpopcallret 的工作方式)我将 pop 编辑到 bx 和然后在我push-ed 到堆栈之后我想要push,在ret 之前我push-ed 到bx(地址ret 应该跳转)然后我@ 987654335@.

代码:

.model small
org 256

.data

    fv db 0
    sv db 0

.code
    jmp start

    f1 proc

        mov cl, 0
        mov ah, 1h
        int 21h

        while:
            cmp al, ' '
            jne true
            je false
            true:
                mov bl, al
                mov al, cl
                sub bl, 30h
                mov dl, 10
                mul dl
                add al, bl
                mov cl, al
                mov ah, 1h
                int 21h
                jmp while
        false:
            pop bx
            mov ch, 0
            push cx
            push bx    
            ret
    f1 endp

    start:
    main proc

        call f1
        pop bx
        mov fv, bl    

    endp
end main

【讨论】:

  • 问题是callret 使用堆栈。要从函数返回,通常使用ax 寄存器。要将参数传递给函数,您通常将它们推入堆栈,使用bp 寄存器访问它们,如我上面的链接中所述,然后使用ret XX 自动弹出它们,返回后要弹出的字节数。
  • 然而,还有许多其他方法可以传递数据。查看有关calling conventions 的维基百科文章以一瞥^^
猜你喜欢
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 2012-06-30
  • 2017-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多