how does calls in a program affect the values in registers?

Hi!
Could you please look at the code below and answer my question below?
Thanks!

mainProg:
MOV AX, 0B800h
MOV ES, AX

;pointing at row 2 and column 10
MOV DI, 160 * ( 2-1 ) + ( 2*10)
MOV AX, 0BCDh; hex for an equal sign
MOV ES:[DI], AX

CALL myProcedure1
CALL myProcedure2
MOV AX, 0BCDh
MOV ES:[DI], AX

myProcedure1 PROC
MOV AX, 0BCDh
MOV ES:[DI], AX
....
RET
myProcedure1 ENDP

myProcedure2 PROC
MOV AX, 0BCDh
MOV ES:[DI], AX
....
RET
myProcedure2 ENDP
.
.
.
.
.
END mainProg


The above program, as I understand would print three equal signs, one after another?! I don't know. I wanna know whether it prints all three of the equal signs one after another...my main question is what happens to the register(AX, ES and DI) after we have been in and out of different sections of codes(i mean in and out of diffrent procedures, like above).

As you can see the very top part of the code would print an equal sign at row 2 and column 10...now afther that...the program processes the calls...inside the call, is DI pointing to row 2 and column 12? since each character eats up two columns of video memory setup...
please let me know if you need more feed back on this question...i could test it myself but i am having other problems already..

Thanks!
Vashuchandra

Comments

  • Standard DOS .asm calls to a PROC doesn't alter any registers
    so values can be passed to the proc by simply moving the values into
    the registers you want and calling the PROC.
    a CALL is nothing more than a JMP NEAR LABEL
    and it pushes the address of the next line onto the stack before it jumps.
    So RET will POP the return address off the stack into IP Instruction Pointer
    CS:IP is where the CPU is working.
    so if you want it to work some place else, you move different values into it.
    MOV CS:IP, VALUE ;fails
    but you can PUSH an address offset onto the stack
    and RET will load it into IP.
    There are CALL FAR and that requires that a Dword is loaded into CS:IP

    Your code reloads AX with the same value that each proc is called with.
    It is easy to test things with small .com files.
    Assemble an .ASM file that has 0=zero in size,
    then put in one instruction, assemble, and run it through a debugger.
    You will see what the .com does that way.
    If you ran your assembled code through a debugger, you will see that
    the CALL doesn't affect the registers.
    Using that same .com technique you can build & test procedures for your program.

    It appears that you are using Video Mode 3 in your Code.
    There are 80x25=2000 characters per screen
    each one has a CHAR & an attribute=color
    so there are 2000 words = 4000 bytes
    MOV WORD [ES:DI],AX ;does not increment DI to the next character position
    STOSW ; will increment DI +2
    it moves AX to ES:DI adr &
    ADD DI,2 ;basicly

    MOV WORD [ES:DI],AX
    INC DI
    INC DI ; will aim DI to the next character position, but STOSW is easy

    good luck
    Bitdog


  • : Standard DOS .asm calls to a PROC doesn't alter any registers
    : so values can be passed to the proc by simply moving the values into
    : the registers you want and calling the PROC.
    : a CALL is nothing more than a JMP NEAR LABEL
    : and it pushes the address of the next line onto the stack before it jumps.
    : So RET will POP the return address off the stack into IP Instruction Pointer
    : CS:IP is where the CPU is working.
    : so if you want it to work some place else, you move different values into it.
    : MOV CS:IP, VALUE ;fails
    : but you can PUSH an address offset onto the stack
    : and RET will load it into IP.
    : There are CALL FAR and that requires that a Dword is loaded into CS:IP
    :
    : Your code reloads AX with the same value that each proc is called with.
    : It is easy to test things with small .com files.
    : Assemble an .ASM file that has 0=zero in size,
    : then put in one instruction, assemble, and run it through a debugger.
    : You will see what the .com does that way.
    : If you ran your assembled code through a debugger, you will see that
    : the CALL doesn't affect the registers.
    : Using that same .com technique you can build & test procedures for your program.
    :
    : It appears that you are using Video Mode 3 in your Code.
    : There are 80x25=2000 characters per screen
    : each one has a CHAR & an attribute=color
    : so there are 2000 words = 4000 bytes
    : MOV WORD [ES:DI],AX ;does not increment DI to the next character position
    : STOSW ; will increment DI +2
    : it moves AX to ES:DI adr &
    : ADD DI,2 ;basicly
    :
    : MOV WORD [ES:DI],AX
    : INC DI
    : INC DI ; will aim DI to the next character position, but STOSW is easy
    :
    : good luck
    : Bitdog
    :
    :
    Bitdog, That was a very good explanation.

    ASHLEY4.
  • Bitdog!
    Thanks a lot. One more quick question.
    What if my section of code is just like below with or without a RET at the end

    myProcedure:
    ...
    ...
    RET ; or without RET

    What about the SP and BP in the case above? How is my code segment stack gonna look like. My main question is what is the difference between a PROC and the one above? Both can be called form the main program. Registerweise what are the differences.

    I was uncertain about that DI not being incremented by two automatically and about the position of instruction pointer after it hit RET. Your previous explanation is indeed great. Thanks a lot. You are a concept builder

    Vashudevchandra


    : Standard DOS .asm calls to a PROC doesn't alter any registers
    : so values can be passed to the proc by simply moving the values into
    : the registers you want and calling the PROC.
    : a CALL is nothing more than a JMP NEAR LABEL
    : and it pushes the address of the next line onto the stack before it jumps.
    : So RET will POP the return address off the stack into IP Instruction Pointer
    : CS:IP is where the CPU is working.
    : so if you want it to work some place else, you move different values into it.
    : MOV CS:IP, VALUE ;fails
    : but you can PUSH an address offset onto the stack
    : and RET will load it into IP.
    : There are CALL FAR and that requires that a Dword is loaded into CS:IP
    :
    : Your code reloads AX with the same value that each proc is called with.
    : It is easy to test things with small .com files.
    : Assemble an .ASM file that has 0=zero in size,
    : then put in one instruction, assemble, and run it through a debugger.
    : You will see what the .com does that way.
    : If you ran your assembled code through a debugger, you will see that
    : the CALL doesn't affect the registers.
    : Using that same .com technique you can build & test procedures for your program.
    :
    : It appears that you are using Video Mode 3 in your Code.
    : There are 80x25=2000 characters per screen
    : each one has a CHAR & an attribute=color
    : so there are 2000 words = 4000 bytes
    : MOV WORD [ES:DI],AX ;does not increment DI to the next character position
    : STOSW ; will increment DI +2
    : it moves AX to ES:DI adr &
    : ADD DI,2 ;basicly
    :
    : MOV WORD [ES:DI],AX
    : INC DI
    : INC DI ; will aim DI to the next character position, but STOSW is easy
    :
    : good luck
    : Bitdog
    :
    :
    :

  • : Bitdog!
    : Thanks a lot. One more quick question.
    : What if my section of code is just like below with or without a RET at the end
    :
    : myProcedure:
    : ...
    : ...
    : RET ; or without RET
    :
    : What about the SP and BP in the case above? How is my code segment stack gonna look like. My main question is what is the difference between a PROC and the one above? Both can be called form the main program. Registerweise what are the differences.
    :
    : I was uncertain about that DI not being incremented by two automatically and about the position of instruction pointer after it hit RET. Your previous explanation is indeed great. Thanks a lot. You are a concept builder
    :
    : Vashudevchandra
    :
    :
    [blue]Every (almost) CALL must be finished with RET. If you do not use RET the stack pointer will be unbalanced and your variables and code flow will be lost. Of course, you can imitate a RET instruction with some ASM code, but you have to balance your SP - it must be the same as before the CALL. Also, the procedures can be enclosed in PROC statements or not - no matter - but RET is a must:
    [code]
    function:
    RET

    foo PROC
    RET
    foo ENDP
    .
    .
    .
    CALL foo ; OK
    CALL function ; Also OK
    [/code]
  • : Bitdog, That was a very good explanation.
    :
    : ASHLEY4.
    :
    [green]
    Thank you, but as I reread it,
    the word choices makes it look like I'm from a foriegn country :)
    I guess Alaska is kinda foriegn :)

    Bitdog
    [/green]

  • [b][red]This message was edited by Bitdog at 2004-3-3 19:47:53[/red][/b][hr]
    Your question about SP & BP seem to come from .asm programming for C language type proc/function calls.

    The C calling convention is basicly that:
    all values for the proc are pushed on the stack first.
    Then the proc is called.
    The proc then, MOV BP,SP
    and gets the values for the proc off the stack.
    BUT, remember the return address is pushed by the CALL also
    so your proc needs to go past that to get to the values for the proc
    MOV AX,[BP+4]
    a CALL NEAR LABEL pushes a WORD on the stack as the return offset,
    BP must go past that to get to the values.
    CALL FAR LABEL pushes a Dword
    MOV AX,[BP+6] ;might be enough to start accesing the LAST PUSHED VALUE
    MOV AX,[BP+8] ;would get at the SECOND TO LAST PUSHED VALUE, etc.

    Upon RET by your proc, (or RETF = RETurn Far)
    Your program is responsible for straighting out the stack
    by POPing off your pushes (values)
    The Stack Pointer (SP) can be saved to memory and restored though
    MOV WORD [MySTK],SP
    PUSH VAL1
    PUSH VAL2
    PUSH VAL3
    CALL APROC
    MOV SP,[MySTK] ; all is SP well again

    This save the SP to memory thingie can also be used to jump out of
    a LOOP, recursive loops, CALLS, etc, that have pushed values on the stack.

    MOV WORD [MySTK],SP ;=[DS:MySTK] remember DS is always default seg reg
    MOV CX,-1
    ALOOP:
    PUSH CX
    DEC AX
    CMP AX,5
    JB XitLOOP ;jump out of loop
    POP CX
    LOOP ALOOP
    XitLOOP:
    MOV SP,[MySTK] ; restore SP

    This same thing can be used in a proc.
    Save your SP at the start of your proc,
    do what you want in the proc (screw up SP but not the return address)
    jump out of loops or recursions
    restore SP from [MySTK] & RET

    Bitdog
    Beware of the C monster &
    may the force of .asm be with you Jedi


  • Asmguru and Bitdog!
    Thanks a lot for your replies. I really appreciate it. You guys have encouraged me a lot in keeping up with asm programming. I am finding it like any other programming, Now I feel like I can everything that I can do with C++. The thing I like most about asm is that I can talk to the processor directly, meaning faster programs. I don't know why my friends in Nepal think its weird for me to learn asm programming. Well I have recommended your tutorials to them.
    Thanks again guys!
    Vashudevchandra




    : [b][red]This message was edited by Bitdog at 2004-3-3 19:47:53[/red][/b][hr]
    : Your question about SP & BP seem to come from .asm programming for C language type proc/function calls.
    :
    : The C calling convention is basicly that:
    : all values for the proc are pushed on the stack first.
    : Then the proc is called.
    : The proc then, MOV BP,SP
    : and gets the values for the proc off the stack.
    : BUT, remember the return address is pushed by the CALL also
    : so your proc needs to go past that to get to the values for the proc
    : MOV AX,[BP+4]
    : a CALL NEAR LABEL pushes a WORD on the stack as the return offset,
    : BP must go past that to get to the values.
    : CALL FAR LABEL pushes a Dword
    : MOV AX,[BP+6] ;might be enough to start accesing the LAST PUSHED VALUE
    : MOV AX,[BP+8] ;would get at the SECOND TO LAST PUSHED VALUE, etc.
    :
    : Upon RET by your proc, (or RETF = RETurn Far)
    : Your program is responsible for straighting out the stack
    : by POPing off your pushes (values)
    : The Stack Pointer (SP) can be saved to memory and restored though
    : MOV WORD [MySTK],SP
    : PUSH VAL1
    : PUSH VAL2
    : PUSH VAL3
    : CALL APROC
    : MOV SP,[MySTK] ; all is SP well again
    :
    : This save the SP to memory thingie can also be used to jump out of
    : a LOOP, recursive loops, CALLS, etc, that have pushed values on the stack.
    :
    : MOV WORD [MySTK],SP ;=[DS:MySTK] remember DS is always default seg reg
    : MOV CX,-1
    : ALOOP:
    : PUSH CX
    : DEC AX
    : CMP AX,5
    : JB XitLOOP ;jump out of loop
    : POP CX
    : LOOP ALOOP
    : XitLOOP:
    : MOV SP,[MySTK] ; restore SP
    :
    : This same thing can be used in a proc.
    : Save your SP at the start of your proc,
    : do what you want in the proc (screw up SP but not the return address)
    : jump out of loops or recursions
    : restore SP from [MySTK] & RET
    :
    : Bitdog
    : Beware of the C monster &
    : may the force of .asm be with you Jedi
    :
    :
    :

  • : Asmguru and Bitdog!
    : Thanks a lot for your replies. I really appreciate it. You guys have encouraged me a lot in keeping up with asm programming. I am finding it like any other programming, Now I feel like I can everything that I can do with C++. The thing I like most about asm is that I can talk to the processor directly, meaning faster programs. I don't know why my friends in Nepal think its weird for me to learn asm programming. Well I have recommended your tutorials to them.
    : Thanks again guys!
    : Vashudevchandra
    :
    :
    :
    [blue]Well, ASM is fine, but still - to make a large project in ASM it is a tricky business - you need a good IDE for this, something like VB, but generating ASM code.

    Also, C++ compilers today can generate code close enough to the ASM code done by a good coder. I mean the professional compilers... but anyway, enjoy ASM!..
    [/blue]
  • : : Asmguru and Bitdog!
    : : Thanks a lot for your replies. I really appreciate it. You guys have encouraged me a lot in keeping up with asm programming. I am finding it like any other programming, Now I feel like I can everything that I can do with C++. The thing I like most about asm is that I can talk to the processor directly, meaning faster programs. I don't know why my friends in Nepal think its weird for me to learn asm programming. Well I have recommended your tutorials to them.
    : : Thanks again guys!
    : : Vashudevchandra
    : :
    : :
    : :
    : [blue]Well, ASM is fine, but still - to make a large project in ASM it is a tricky business - you need a good IDE for this, something like VB, but generating ASM code.
    :

    : Also, C++ compilers today can generate code close enough to the ASM code done by a good coder. I mean the professional compilers... but anyway, enjoy ASM!..
    : [/blue]
    :

    You should not try to discourage some one, who as seen the POWER that asm give you.

    1)Big programs can be broken down in to small section (eg:inc).
    2)We do not need big programs,we should demand programs that get smaller with every up date,(eg: web browsers have a 100 functions,90 functions i have never used and do not need).
    3)Jobs there is a shortage of x86 asm programmers (there is no shortage of c++ programmers).
    4)ASM is the most logical programing language.

    ASHLEY4.
  • : : : Asmguru and Bitdog!
    : : : Thanks a lot for your replies. I really appreciate it. You guys have encouraged me a lot in keeping up with asm programming. I am finding it like any other programming, Now I feel like I can everything that I can do with C++. The thing I like most about asm is that I can talk to the processor directly, meaning faster programs. I don't know why my friends in Nepal think its weird for me to learn asm programming. Well I have recommended your tutorials to them.
    : : : Thanks again guys!
    : : : Vashudevchandra
    : : :
    : : :
    : : :
    : : [blue]Well, ASM is fine, but still - to make a large project in ASM it is a tricky business - you need a good IDE for this, something like VB, but generating ASM code.
    : :
    :
    : : Also, C++ compilers today can generate code close enough to the ASM code done by a good coder. I mean the professional compilers... but anyway, enjoy ASM!..
    : : [/blue]
    : :
    :
    : You should not try to discourage some one, who as seen the POWER that asm give you.
    :
    : 1)Big programs can be broken down in to small section (eg:inc).
    : 2)We do not need big programs,we should demand programs that get smaller with every up date,(eg: web browsers have a 100 functions,90 functions i have never used and do not need).
    : 3)Jobs there is a shortage of x86 asm programmers (there is no shortage of c++ programmers).
    : 4)ASM is the most logical programing language.
    :
    : ASHLEY4.
    :

    And C is so much easier to use when you know what the compiler is doing.

    I find myself incapable of using Java because I'm so used to treating strings as character arrays. It's also a real pain not being able to use memcpy to copy arrays under Java...

    I now find myself thinking in terms of C++ and ASM algorithms, which makes learning a declarative language like Haskell damned difficult. And ultimately pointless, as in: 'Why should I need to prototype this algorithm? It's already in C++, in final form, in my mind! Rewriting it in a declarative language is just a waste of time.'

  • : You should not try to discourage some one, who as seen the POWER that asm give you.
    :
    : 1)Big programs can be broken down in to small section (eg:inc).
    [blue]Good point! Completely agree.[/blue]

    : 2)We do not need big programs,we should demand programs that get smaller with every up date,(eg: web browsers have a 100 functions,90 functions i have never used and do not need).

    [blue]I mean big not in size, but in functionality. ASM gives you both: small room can fit more functionality if your project is broken into small pieces, like bricks in a house. But, again, here you need a good IDE to keep track of the thousands of functions and objects.[/blue]

    : 3)Jobs there is a shortage of x86 asm programmers (there is no shortage of c++ programmers).

    [blue]I think there is a very little jobs on x86 Assembler. Atleast when I look on the job search engines - there is almost none.[/blue]

    : 4)ASM is the most logical programing language.
    [blue]That depends on how you write your code - if you do not use macros, functions and structures - you will not be able to recognize your own code in a year or two...
    [/blue]
    :
    : ASHLEY4.
    :

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories