2

Well, recently I started learning Assembly 8086 out of curiosity mostly.

Input in assembly allows you to type only one character, so I tried to make a program in Assembly 8086 that allows you to enter multi-digit integer input, ending the input with "space"(' '), then adding the number and printing the value.

I saw that push and pop can be used to pass arguments to a procedure but I tried to use them to make my procedure return something and store it to a variable, I couldn't imagine a way to do this with ret based on my knowledge on Assembly 8086 so...anyway, I made a procedure, but for some reason the ret at the end of the procedure doesn't seem to work and the procedure runs infinite times.

The code so far:

.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
platinoob_
  • 151
  • 1
  • 11

1 Answers1

1

Well, I found it, before I push anything else to the stack(I searched how push, pop, call and ret work)I pop-ed in to bx and then after I push-ed to the stack what I wanted to push, before ret I push-ed what was to bx(the addres ret was supposed to jump) and then I ret.

Code :

.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
platinoob_
  • 151
  • 1
  • 11
  • Maybe this helps: https://stackoverflow.com/a/60607905/1871033 – CherryDT Apr 15 '20 at 12:39
  • 1
    The issue is that `call` and `ret` _also_ use the stack. To return from a function, you usually use the `ax` register. To pass arguments into a function, you usually push them onto the stack, access them with the `bp` register as explained in my link above, and later auto-pop them using `ret XX` with the number of bytes to pop after returning. – CherryDT Apr 15 '20 at 12:40
  • There is however a multitude of other ways to pass data around. Check the Wikipedia article about [calling conventions](https://en.wikipedia.org/wiki/X86_calling_conventions) to get a glimpse ^^ – CherryDT Apr 15 '20 at 12:41