64-bit Basm Learning Essays (i)

Source: Internet
Author: User
Tags stack pop

??

64-bit Basm Learning Essays (i)

Delphi's basm has always been my favorite embedded assembly language, it is more convenient and more flexible than the inline assembler of C + +, because the inline assembler of C/s + + can only be or plug-in assembly code, function behind the curly braces hidden function framework, restricting the play of assembly code, If there are no parameters and local variables, there is always a stack frame, it is more annoying that as long as you use the ESI,EDI,EBX register in the function, you will automatically save and restore, so that these registers can not be passed between the functions of information, etc., and the Delphi Basm may be a plug-in assembly code, It is also a complete compilation method, under the complete assembly method, how to play is their own business.
After Delphi XE2 can write 64-bit applications, but I have not time to try 64-bit BASM code has no change, the Spring Festival before and after the time to study, found that 64 basm change is still very large, not only a simple register bit longer problem, But the framework of the entire basm approach (not just the basm, but the entire 64-bit Computer application framework) has changed radically, from the point of view of writing program code, which seems to be larger than the previous 16-bit program to the 32-bit program step.
One, 64-bit basm does not support inserting assembly code, only the pure Basm method can be written. The following code is incorrect:

function Test (V:integer): Integer;
Var
I:integer;
Begin
I: = v * v;
Asm
mov eax, I
End
End

It can only be written like this:

function Test (V:integer): Integer;
Asm
mov eax, V
Imul eax, eax
End

The second, 64-bit basm only supports one invocation mode, regardless of whether you indicate stdcall,pascal,cdecl or not, the invocation method is the register parameter pass, the clearing stack is responsible for the calling methods (similar to cdecl). This change is not just basm, it seems like the entire 64-bit program, with only one invocation. The Stdcall,pascal,cdecl invocation description is only compatible with 32-bit program code and does not error.
Three, 64-bit BASM data type in addition to the pointer type from the 32-bit advanced 64-bit, the other unchanged, the most commonly used integer, Longword length is still four bytes (the previous few days according to the online, Delphi XE8 Longword will be changed to 64-bit).
Four, 64-bit register changes.
1, register length increased by one times, from 32 bit to 64 bits, EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP and so on into RAX,RBX,RCX,RDX,RSI,RDI,RBP,RSP, of course, e-head register can be used for 32-bit register , the same 16-bit, 8-bit register can also be used.

Here is one thing to pay special attention to, and in 64-bit programs, the default operand length is still 32 bits, only the default address length is 64 bits, which is somewhat different from the 16-bit advanced 32 bit, the low 16 bit of the operation register will not affect its high 16 bits, and 64 bit, change register low 32 bits, Causes a high 32-bit zeroing of the register. As in the following code:

mov eax, edx
SHL Rax, 32
mov eax, edx

The intention is to form a 2 parallel 32-digit number in the Rax, the result of the third code leads to Rax high 32-bit zeroing, using or EAX, edx is also the same will lead to high 32-bit zeroing, only or Rax, RDX is correct (of course, to ensure that RDX high 32 bits is 0).

In addition, the operation of the 64-bit address should also be noted that although the 64-bit program address by default is 64 bits, but the use of similar [Esi+edx] 32-bit address operation will not be error, the same operation results seem to be correct, but I think, should try to avoid such code, because it seems that the results are correct, Mainly because the application can manipulate the length of the data is not more than 32 bits, if later with the hardware changes, the system will also change, once the application can use more than 32 bits of data, your code is a problem. There is also the increase or decrease of the address, whether 32-bit or 64-bit code, integer length or 32-bit, if the operand of the increment and decrement address is 32 bits, preferably converted to 64 bits, unless you can guarantee that it is positive, such as the following procedure:


function Test (V:integer): Integer;
Asm

Push RBX
mov eax, V
Add RBX, Rax

.......

Pop RBX

End

The parameter v is a 32 integer, and it is easy to add a problem directly with the address RBX unless you can guarantee that V is not negative. This can be extended with CDQE or by using Movsxd Rax, v.

The operands of the

    push and stack pop statements can only be 64 bits, such as push  eax is wrong.
    2, General register more than R8-R15 8 registers, in the Basm method, R8-r11 can be used directly, and r12-r15 in use with the same as RSI,RDI,RBX, should pay attention to save and restore. The R8-R15 is a 64-bit form and can also be expressed as 32-bit, 16-bit, and 8-bit, such as r8,r8d,r8w,r8b 64-bit, 32-bit, 16-bit and 8-bit, and 64-bit bad, RSI, RDI,RBP,RSP can also be operated with SIL,DIL,BPL and SPL low 8 bits. R8-r15 Unlike the RAX,RBX,RCX,RDX several general-purpose registers have high-low 8-bit registers, and the previous universal register of the upper 8-bit can not be used in the same statement with the R8-R15 register, such as mov  Ah, r8b; mov  BH, [R8] and so on are all wrong.
    3, the XMM register is also 8, in turn, XMM8-XMM15, however, XMM6-XMM15 should be aware of the use of saving and recovery (XMM6,XMM7 in 32-bit code is not required to protect). Saving SSE registers is cumbersome, it cannot be used as a regular register with a stack and a stack of statements, but there is a savenv pseudo-directive in basm is very convenient (I do not know whether this is basm unique, or other compilations common), such as .savenv  xmm7 (note savenv before a point) , the Delphi compiler adds statements that protect and restore XMM7 registers in the Basm method.
    Four-, 64-bit Basm method The default parameter pass changes. Whether it is a 32-bit or 64-bit Basm method, the default is to use the register to pass parameters, the difference is that the 32-bit basm is the first 3 parameters non-floating-point parameter using the Register pass, starting from the left side of the parameter, followed by ECX,EDX,ECX, floating-point parameter and three non-floating-point parameters using the Stack Pass While the 64-bit basm is the first 4 parameters are passed using the register, if the non-floating-point parameter, starting from the left side of the parameter, followed by RCX,RDX,R8,R9, the floating-point number is passed with XMM0-XMM3. In a 32-bit method, when a floating-point number is sandwiched between the first 3 parameters, the Register parameter is deferred, as in method:

function Test (v1, v2:integer; v3:double; v4:integer): double;

Asm

FLD v3

End

Register use: EAX=V1,EDX=V2,[EBP+8]=V3,ECX=V4, here the ECX is postponed. The 64-bit method does not postpone, regardless of whether the floating-point number, the position of the register is not changed, such as the following method:

Procedure Test (v1, v2:integer; v3:double; v4, V5:int64);

Asm

End

Register using: ecx=v1,edx=v2,xmm2=v3,r9=v4,[rsp+28h] (no frame) or [rsp+30h] (with frame) =v5, if V3 is a non-floating-point number, the register should be R8, here with xmm2 to represent the floating-point parameter, The R8 register is not postponed, and the same V3 does not use XMM0, but is strictly arranged xmm2 by position parameter location. As for the parameter V5 is passed using the stack, as the offset position in its stack is 28h or 30h, rather than 8 and 16 behind the reason is specifically discussed.

Five, 64-bit BASM the return value changes. The return value of the 64-bit Basm method also has some transformations, the general return value is either EAX or Rax, most notably the ability to return a 64-bit integer type with Rax instead of using Edx:eax to return. The return value of a floating-point number is the most varied, as the previous 32-bit test function code is passed using the FLD v3 through the 80x87 register, which is wrong with the 64-bit basm function, because the 64-bit function returns the floating-point numbers and no longer uses the 80x87 register. Instead, the SSE register XMM0 is used, so the 64-bit code can only be similar to Movaps xmm0, v3 or directly movaps xmm0, xmm2.

There is also a special return value, such as the following method, that returns a Trect type:


function GetRect (left, Top, right, Bottom:integer): Trect;
Asm

32-bit code:

Push EBX

mov ebx, Result//or MOV ebx, [ebp+8]

mov [EBX]. Trect.left, EAX

mov [EBX]. Trect.top, edx

mov [EBX]. Trect.right, ECX

mov eax, Bottom//or mov eax, [ebp+12]

mov [EBX]. Trect.bottom, EAX

Pop ebx

64-bit code:
mov [RCX]. Trect.left, edx
mov [RCX]. Trect.top, r8d
mov [RCX]. Trect.right, r9d
mov eax, Bottom
mov [RCX]. Trect.bottom, EAX

End

By contrast, it can be seen that the return value of this structure, if it is less than or equal to the general register of the even-byte structure using EAX or Rax return, this point 32-bit and 64-bit code is the same, and the other structure return value is different, 32-bit code is passed as the last stack parameter of the structure address, While the 64-bit code uses the first parameter to pass the structure address, specifically by RCX, the following is a call to the BASM process example:

Procedure Test;
Var
R:trect;
Asm
. Params 5

r: = GetRect (1, 2, 3, 4)
Lea RCX, R
mov edx, 1
MOV r8d, 2
MOV r9d, 3
mov [ebp+20h], 4
Call GetRect
End

The register used to pass the first parameter rec is occupied by the return value, or the return value of this structure is passed as the first parameter, and the preceding GetRect function is actually a variant of the following form:

Procedure GetRect (Var r:trect; Left, Top, right, Bottom:integer);

In the invocation example process, there is a pseudo-directive. The params is used to automatically allocate the parameter memory space, and the parameter bottom is also used to pass the stack, but does not use the pressure stack directive, the specific reason relates to 64-bit function architecture, more complicated, because today's time is not early, tomorrow continues ...


64-bit Basm Learning Essays (i)

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.