Assembly Language---Call and ret directives

Source: Internet
Author: User
Tags mul

Assembly language--call and RET directives

Call and RET instructions

Both call and RET directives are transfer directives, both of which modify the IP, or both CS and IP.

They are often used together to implement sub-program design.

RET and RETF

The RET instruction uses the data in the stack to modify the contents of the IP so as to realize the near transfer.

The RETF instruction uses the data in the stack to modify the contents of CS and IP so as to achieve far transfer.

When the CPU executes the RET instruction, the following two steps are taken:

(1) (IP) = ((ss) *16 + (sp))

(2) (sp) = (sp) +2

When the CPU executes the RETF instruction, the following four steps are performed:

(1) (IP) = ((ss) *16) + (SP)

(2) (sp) = (sp) + 2

(3) (CS) = ((ss) *16) + (SP)

(4) (sp) = (sp) + 2


To interpret the RET and RETF instructions using the assembly syntax:

When the CPU executes a RET instruction, it is equivalent to:

Pop IP

When the CPU executes the RETF instruction, it is equivalent to:

Pop IP

Pop CS

Call command

When the CPU executes the call command, two steps are taken:

(1) Press the current IP or CS and IP into the stack; (Note that the current IP is pressed into the stack, not the next statement's IP address is pressed into the stack)

(2) Transfer.

The call instruction does not implement a short transfer, except that the call instruction implements the transfer method in the same way as the jmp instruction.

Call instruction for transfer based on displacement

Call label (after the current IP stack, go to the label to execute the instructions)

When the CPU executes the call instruction in this format, the following actions are performed:

(1) (sp) = (sp)-2

((ss) *16 + (sp)) = (IP)

(2) (IP) = (IP) + 16-bit displacement.

16-bit displacement = The address of the first byte after the address-call instruction at the "label";

The range of 16-bit displacement is -32768~32767, which is indicated by complement;

A 16-bit displacement is calculated by the compiler at compile time.

To interpret the call instruction in this format using the assembly syntax:

When the CPU executes the command "call label", it is equivalent to:

Push IP

JMP near PTR label

The call instruction of the destination address of the transfer in the instruction

The call instruction mentioned earlier, the corresponding machine instruction does not have the destination address of the transfer, but the transfer displacement relative to the current IP.

The directive "call far PTR designator" implements the transfer between segments.

When the CPU executes the call instruction in this format, the following actions are performed:

(1) (sp) = (sp)-2

((ss) *16+ (sp)) = (CS)

(sp) = (sp)-2

((ss) *16+ (sp)) = (IP)

(2) (CS) = Segment Address of the segment where the label is located

(IP) = The offset address of the label in the segment

To interpret the call instruction in this format using the assembly syntax:

When the CPU executes the command "Call far ptr designator", it is equivalent to:

Push CS

Push IP

JMP far PTR designator

Call instructions for transferring addresses in registers

Instruction format: Call 16-bit register

Function:

(sp) = (sp)-2

((ss) *16+ (sp)) = (IP)

(IP) = (16-bit register)

The call instruction in this format is interpreted using the assembly syntax, which is equivalent to when the CPU executes call 16-bit REG:

Push IP

Jum 16-bit Register

Transfer address in-memory call instruction

There are two types of formats:

1) Call Word PTR memory unit address

Equivalent:

Push IP

Jum Word PTR memory cell address

2) Call DWORD PTR memory Unit address

Equivalent:

Push CS

Push IP

JMP DWORD PTR memory Unit address

Use of call and RET

How to use them together to implement the mechanism of the subroutine.

The framework of the subroutine is as follows:

Instructions

Ret

The framework for the source program with the subroutine is as follows:

Assume Cs:code

Code segment

Main: ...; Main program

...

Call sub1; Calling subroutine Sub1

...

MOV ax,4c00h

int 21h

Sub1: ...; Subroutine Sub1 start

...

Call Sub2; Calling subroutine Sub2

...

RET; sub-program return

SUB2: ...; Subroutine Sub2 start

...

RET; sub-program return

Code ends

End Maint

--------------------------------------------------------------------------------

Modular programming

The call and RET directives support the modular design of assembly language programming together.

In practical programming, the modularity of the program is essential.

Because the problem of realization is more complicated, it is a necessary solution to transform it into a sub-problem of interrelated and different levels when analyzing the real problem.

The call and RET directives provide procedural support for this method of analysis.

Using the call and RET instructions, we can solve a complex problem by using a simple method to realize multiple interrelated and functionally independent subroutines.

Issues with parameters and results passing

Subroutines generally have to handle a certain transaction according to the parameters provided, and after processing, the result (return value) is provided to the caller.

In fact, we discuss the issue of parameter and return value passing, which is actually the discussion of how to store the parameters required by the subroutine and the resulting return value.

; Description: Calculates the 3-th square of n

; parameter: (BX) =n

; results: (Dx:ax) =n^3

Cube:mov AX,BX

Mul BX

Mul BX

Ret

Note that the good style of programming should be commented in detail. Contains descriptions of the functions, parameters, and results of the child program.

Using registers to store parameters and results is the most commonly used method. For the register that holds the parameter and the register that holds the result, the caller and subroutine read and write the opposite: The caller sends the parameter into the parameter register, takes the return value from the result register, the subroutine takes the parameter from the parameter register, and feeds the return value into the result register.

Delivery of bulk data

The number of registers is ultimately limited, and we cannot simply use registers to hold multiple data that need to be passed. The same problem applies to the return value. At such times, we put the bulk data into memory and then put the first address of the memory space in the register, passing it to the required subroutine. The same method can be used for return results with bulk data. In addition to the use of registers to pass parameters, there is also a common method is to use the stack to pass parameters.

Issues with Register conflicts

A generalization of the problem, the register used in the subroutine, is likely to be used in the main program, causing the register to use the conflict.

So how do we avoid this conflict? At a glance, there are two options:
1) When writing a program calling subroutines, be careful to see if there are any registers in the subroutine that are used to generate the conflict, and if so, the caller uses a different register;
2) When writing subroutines, do not use registers that create conflicts.
The above two scenarios, is not feasible, the first to call the subroutine program writing caused great trouble. The second is not possible, and the subroutine cannot know the future invocation situation.

We want to:
1) When you write a program that calls subroutines, you don't have to worry about which registers are used by the sub-program;
2) do not care about which registers are used by the caller when writing subroutines;
3) There is no register conflict.

The simplest way to solve this problem is to save the contents of all the registers used in the subroutine at the beginning of the subroutine and restore them before the subroutine returns. We can use the stack to save the contents of the register.

Later, our standard framework for writing subroutines is as follows:

Subroutine start: The register used in the subroutine into the stack

Sub-Program content

Register out-of-stack used in sub-programs

Return (ret, RETF)

Note the order in which the registers are in and out of the stack.

Experiment 10 Writing subroutines

1. Display string

Problem: The display string is often used in real work, you should write a generic subroutine to implement this function. We should provide a flexible invocation interface so that callers can decide where to display (rows, columns), content, and colors.

Sub-Program Description

Name: Show_str

Function: Displays a string ending with 0 in the specified position, with the specified color.

Parameters: (DH) = line number (value range 0~24), (DL) = column number (value range 0~79),

(CL) = color, Ds:si points to the first address of the string

return: None

Example of application: in 8 rows and 3 columns of the screen, the string in the data segment is displayed in green.

1) The entry parameters of the subroutine are the line number and the column number on the screen, note that in the subroutine to convert them to the address in the video memory, first of all to analyze the screen column position and memory address of the corresponding relationship.

2) Note the relevant registers used in the Save subroutine.

3) The internal processing of the empty upper subroutine is closely related to the structure of the memory, but it provides an interface independent of the memory structure. By calling this subroutine, the display of the string can be done without having to understand the structure of the video memory, which provides convenience for programming. In the experiment, pay attention to realize this design idea.

2, solve the problem of division overflow

Problem: Div commands can do division. When 8-bit division is performed, the quotient of the result is stored with Al, Ah stores the remainder of the result, and when the 16-bit division is performed, the quotient of the result is stored with AX, and the remainder of the DX is stored. However, now there is a problem, if the result quotient is greater than AH or AX can store the maximum value, then what?

When the CPU performs division instructions such as Div, if the resulting data exceeds the range that the register can store, it will throw an internal error on the CPU, which is called a division overflow.

Sub-Program Description

Name: DIVDW

Function: The division operation does not produce overflow, the divisor is the DWORD type, the divisor is word type, the result is DWORD type.

Parameters: (AX) Low 16-bit for type =dword data

(DX) High 16 bits of =dword type data

(CX) = divisor

return: (DX) = high 16 bits of result, (ax) = Low 16 bits of result

(CX) = remainder

Application Examples: Computational 1000000/10 (F4240H/0AH)

3. Numerical display

Problem: Programming: Displays the data in a field in decimal form.

Data is binary information in memory, and the size of the value is marked. To display them on the screen as information that we can read, we need to transform the information.

For example, the value 12666, stored in the machine as binary information: 11000101111010B (317AH), the computer can understand it. And we have to read on the display of the understandable value 12666, we should see a string of characters: "12666", because the video card follows the ASCII encoding, in order to allow us to see this string of characters on the display, it should be in the form of ASCII code stored in the machine as: 31H, 32H, 36H , 36H, 36H (the ASCII code corresponding to the character "0" ~ "9" is 30h~39h).

As you can see from the above analysis, in the conceptual world, there is an abstract data 12666, which represents the size of a numeric value. In the real world it can have many representations, can be in the electronic machine in the form of high and low level (binary), can also be on paper, blackboard, on the screen in human language "12666" to write. Now, the problem we are facing is to convert the same abstract data from one representation to another.

To display the data in decimal form on the screen, you need to work in two steps:

1) Convert the data stored in binary information into a string in decimal form;

2) displays a string in decimal form.

Sub-Program Description

Name: Dtoc

Function: Converts Word data to a string representing a decimal number, with a string ending with 0.

Parameters: (AX) =word type data

Ds:si point to the first address of the string

return: None

Application Example: Programming, the data 12666 in the form of a decimal in the screen 8 rows 3 columns, shown in green.

Analysis: To get the string "12666", is to get a list of ASCII code representing the string: 31H, 32H, 36H, 36H, 36H.

The ASCII code corresponding to the decimal digit character = decimal Digital value +30h.

To get a string representing a decimal number, first seek the value of each bit of decimal number.

For example, for 12666, the value of each bit is evaluated first: 1, 2, 6, 6, 6. By adding these numbers separately 30H, we get the ASCII code string representing 12666, 31H, 32H, 36H, 36H, 36H.

So, how do you get the value of each bit? The following methods are used (except for the 10 redundancy method):

12666/10=1266 ... 6

1266/10=126........6

126/10=12 ..... 6

12/10=1...........2

1/10=0...........1

Visible, with 10 in addition to 12666, a total of 5 times, note each time the remainder, you get the value of each bit.

Combined with the above analysis, the process can be concluded as follows:

Divide by 12666 by 10, Loop 5 times, write down the remainder of each time, and add 30H each time, so that the ASCII string representing the decimal number is obtained.

As long as the quotient is 0, everyone's values have been calculated. You can use the JCXZ directive to implement related functions.

Reference: http://blog.csdn.net/trochiluses/article/details/19358289

Assembly Language---Call and ret directives

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.