把x指针指向的4个字节次序颠倒过来

举例:x指向的内存地址,其字节内容从低到高依次分别为c1,c2,c3,c4(Delphi读取一个integer的时候,结果是c4c3c2c1,其排列规则是"高高低低"),那么结果是c4,c3,c2,c1(Delphi读取一个integer的时候,结果是c1c2c3c4)

用delphi写的程序,把x指针指向的4个字节次序颠倒过来:

function toulong(x: pchar): longword;
begin
result := (longword(x^) shl 24) or
(longword((x + 1)^) shl 16) or
(longword((x + 2)^) shl 8) or
(longword((x + 3)^));
end;

以下是用delphi的嵌入式汇编写法:

function toulong(x: pchar): longword;
asm
mov esi,eax // 读取x指针的值(也就是某一个内存地址)到esi(esi是通用寄存器,一般可以随便使用)。即esi=x
mov ax,[esi] // 从这个内存地址里读取两个字节的内容到ax里。即ax=c2c1(注意,intel倒着吃)
xchg ah,al // 把ax里两个字节位置交换一下。即ax=c1c2
shl eax,16 // 交换完以后左移到eax的高2位字节。即eax=c1c200
mov ax,[esi+2] // 把esi往后移动2个字节读取内存数据到ax里,即ax=c4c3(注意,intel倒着吃)
xchg ah,al // 把ax里两个字节位置交换一下。即ax=c3c4。加上之前计算好的eax高2位字节,结果即此时eax=c1c2c3c4,如果写回内存的话,内存里的值从低到高依次为c4c3c2c1,但Delphi倒着吃,又会读出一个integer的数据为c1c2c3c4)
end;

说明:默认情况下,delphi使用“register”方式,若参数在3个已内,将分别使用eax、edx和ecx,超过3个参数部分将使用堆栈。返回参数的存放视长度而定,例如8位用al返回,16位用ax,32位用eax,64位用用两个32位寄存器edx:eax,其中eax是低位。

效率:本例asm大约比delphi或c快50%。

======================================================

做了个Delphi程序验证:

procedure TForm1.Button3Click(Sender: TObject);
var
i: integer;
p: PInteger;
x: PChar;
begin
i:=$04030201; // 注意,只有这样,才会内存的值从低到高依次是01020304
p:=@i;
ShowMessage(IntToStr(Integer(p^)));
x:=pchar(p);
ShowMessage(IntToStr(toulong(x)));
end;

Hex 01020304 = Dec 16909060
Hex 04030201 = Dec 67305985

注意,观察这个的汇编代码,很有意思。

======================================================

再用VC写一遍,汇编代码主体都不必,就是改变了关于参数传递约定那部分

#include "stdafx.h"

int toulong(char* p)
{
    int fff;
    __asm {
        mov eax, p // EAX不再是第一个参数的值了,所以要自己写
        mov esi,eax 
        mov ax,[esi] 
        xchg ah,al 
        shl eax,16 
        mov ax,[esi+2] 
        xchg ah,al 
        mov fff, eax // EAX不再是自动的返回值了,所以要自己写
    }
    return fff;
}

int main(int argc, char* argv[])
{
    int i=0x04030201;
    printf("after: %d !
", i);
    int* p=&i;
    int j=toulong((char*)p);
    printf("after: %d !
", j);
    return 0;
}

===========================================

不清楚对象在内存里的排列是怎么个倒序。以后再研究。

原文地址:https://www.cnblogs.com/findumars/p/3717999.html