this blog series reference from << assembly Language >> third edition, author: Wang Shuang
Call and RET are transfer instructions, they can change the IP value, or also change the value of CS and IP, often in the program using them for the design of sub-program module.
10.1 ret and RETF
RET uses stacks of data to modify the contents of the IP to achieve near-transferRETF the contents of CS and IP with the data in the stack, realize the remote transfer
ret Execution steps:(1):(IP) = ((SS) *16+SP)
(2):(SP) = (sp) +2
RETF Execution steps: (1):(IP) = ((SS) *16+SP)
(2):(SP) = (sp) +2(3):(CS) = ((SS) *16+sp)
(4):(SP) = (sp) +2
ret can be understood as: POP IPRETF can be understood as: Pop IP pop CS
Here's an example:
Assume Cs:codestack segment db-dup (0) stack endscode segment mov ax,4c00h int 21hstart:mov ax,stack mov ss,ax mov sp,16 mov ax,0 push CS push ax mov bx,0 retf code endsend Start
Use the Debug tool to step through the following:
as can be seen, after the execution of RETF, Cs:ip point to the first sentence: mov ax,4c00h
10.2 Call Command
the execution step of the call instruction (call cannot achieve a short transfer):(1) Press the current IP or CS and IP into the stack(2) Transfer
10.3 Call instructions for shifting based on displacement
Call label (the current IP stack is transferred to the label for execution)To perform the steps:(1) (sp) = (sp)-2((ss) *16+ (sp)) = (IP) (implements the current IP value stack)
(2) (IP) = (IP) + 16-bit displacement (transferred to the label) 16-bit displacement = address of the first byte after the address of the label at the-call instruction
The displacement range is-32768-32767 is given by the complementdisplacement is calculated at compile time
Call label equals call near PTR designator
10.4 The destination address of the transfer in the command call instruction
there is no destination address in the machine code corresponding to the call label instruction, including the displacement of the label at the current IPcall far PTR designator gives the destination address directly in the machine code to achieve inter-segment transferthe steps to perform are:(1) (sp) = (sp)-2( (ss) *16+ (sp)) = (CS) (sp) = (sp)-2((ss) *16+ (sp)) = (IP) (IP and CS stack)(2) (CS) = segment address where the label is located(IP) = offset address where the label is located
The call far PTR designator is equivalent to:Push Cspush ipjmp far ptr designator
10.5 Call instructions for transferring addresses in registers
Instruction format: Call 16-bit Register execution steps: (sp) = (sp) -2 ((SS) *16+ (sp)) = (IP)
(IP) = (16-bit register)The call 16-bit register is equivalent to:
PUSH IP jmp 16-bit registers
10.6 Transfer address in-memory call instruction
two different formats:a call word ptr memory addressequivalent: Push IPjmp word ptr memory address
Two call DWORD ptr memory address equivalent to: Push CS push IP jmp DWORD ptr memory address
use of 10.7 call and RET
After executing the following code, the value in the BX register is:
Assume Cs:codecode Segmentstart:mov ax,1 mov cx,3 call s mov bx,ax mov ax,4c00h int 21h S:add Ax,ax Loop s retcode endsend start
Debug step execution results See (BX) =8 analysis steps are as follows: 1.cpu reads the machine code of call S, IP points to call after the instruction mov bx,ax, then the CPU executes the call s instruction, the current IP (instruction mov bx,ax offset address) pressure stack, and change the IP to the offset address of the label S. 2.cpu from the marking S start execution, after the loop, (AX) =83.cpu the RET machine code read, IP point to the RET instruction memory unit, then the CPU executes the RET instruction, from the stack (that is, previously pressed into the stack of MOV bx,ax offset address) POPs a value into the IP, At this point Cs:ip point to MOV bx,ax4.cpu from mov bx,ax start execution, until the end
10.8 mul Directive
Mul as a multiplication instruction, by the following rule 1. All 8-bit multipliers, one placed in Al, the other in 8-bit registers or in memoryare 16-bit multipliers, one placed in Ax, the other in 16-bit registers or in memory2. Result: If the multiplier is 8 bits, the result is placed in ax, if the multiplier is 16 bits, the high position is placed in DX, the low position is placed in the axformat:mul Regmul Memory UnitFor example:mul byte ptr ds:[0] meaning: (AX) = (AL) * ((DS) *16+0);mul word ptr [bx+si+8] meaning: (DX) = (AX) * ((DS) *16+ (BX) + (SI) +8) result of high 16-bit(DX ) = (AX) * ((DS) *16+ (BX) + (SI) +8) Results of low 16-bit
10.9 Modular programming and parameter and result transfer problems
The use of call and RET can make the program achieve the problem of modular design, which is very useful when writing a large-scale program, the logic of the modular program is clear, and the module code can be reused. The subroutine needs to return the results to the caller after execution of the program function is completed. Here we need to consider how to store and pass the parameters and return values required by the subroutine.
a problem, for example, is to design a subroutine that provides a parameter n, which computes the three-th square of N. There are two questions here:(1) Where to store the parameter n(2) the calculated values are stored somewhere.
Here we can put the parameter n into the register BX, the results are placed in DX and ax, because it is to ask three times, we can use two times mul instructions to complete. The code is as follows:
Cube:mov ax,bx mul bx mul BX ret
The use of registers is a common method of passing parameters and results, and parameters are passed to the parameter register at the time of invocation. When the call returns, the result is stored in the result register. Although this method is commonly used, one drawback is that the number of parameters and results passed is limited because the number of registers is limited.
10.10 Delivery of batch data
How to resolve the limit of the number of registers before passing the parameters and results through the register, resulting in the way that the register passes parameters or results when there are many parameters. At such times, we need to put the parameters to be passed in memory, and then put the first address of the memory address in the register, passed to the subroutine. This method is also used for bulk return results. as an example, you need to convert all characters in a string to uppercase letters. we can store a string in a contiguous area in memory and then save that memory address in a register. Iterate through the memory through the loop instruction to remove each character and then convert the case. The results are as follows:
Assume Cs:codedata segment db ' conversation ' data endscode Segmentstart:mov ax,data mov ds,ax mov si,0 ;d S:si points to the first address of the space where the string (bulk data) is located mov cx,12 ; CX Store the length of the string call capital mov ax.4c00h int 21hcaptical:add byte ptr [si],11011111b loop captical retcode endsend start
10.11 Issues with Register conflicts
Register conflict means that registers used in subroutines are most likely to be used in the main program, which can cause conflicts in the use of registers. To solve this problem is to save all the values of the registers used in the subroutine at the beginning of the subroutine, and then restore them before the subroutine returns. You can use the stack to save the contents of the register. The framework for writing subroutines later is as follows:
Subroutine start: subroutine use register stack subroutine content subroutine use register out stack return (RET,RETF)
we modified the sub-program capital in 10.10 to prevent the hosting conflict, as follows:
Captical:push CX push sichange: mov cl,[si] mov ch,0 jcxz ok and byte ptr [si],11011111b Inc si imp short changeok: pop si pop cx RET
Assembly Language Learning Tenth chapter-call and RET directives