把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 ) or
(longword((x + )^) shl ) or
(longword((x + )^) shl ) or
(longword((x + )^));
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, // 交换完以后左移到eax的高2位字节。即eax=c1c200
mov ax,[esi+] // 把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:=$; // 注意,只有这样,才会内存的值从低到高依次是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,
mov ax,[esi+]
xchg ah,al
mov fff, eax // EAX不再是自动的返回值了,所以要自己写
}
return fff;
} int main(int argc, char* argv[])
{
int i=0x04030201;
printf("after: %d !\n", i);
int* p=&i;
int j=toulong((char*)p);
printf("after: %d !\n", j);
return ;
}
===========================================
不清楚对象在内存里的排列是怎么个倒序。以后再研究。
把x指针指向的4个字节次序颠倒过来的更多相关文章
- restrict关键字(暗示编译器,某个指针指向的空间,只能从该指针访问)
我们希望某个对象(内存空间)不被修改的通常做法是什么?声明该空间的const类型,但是这样真的可以吗?是不是的,由于const空间对象的指针是可以付给一个非const值指针的.所以这仍然无法不让该空间 ...
- 指针的指针&指向指针数组的指针
一.指针的指针 指针的指针看上去有些令人费解.它们的声明有两个星号.例如: char ** cp; 如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针 ...
- OC3-父类指针指向子类对象
// // Cat.h // OC3-父类指针指向子类对象 // // Created by qianfeng on 15/6/17. // Copyright (c) 2015年 qianfeng. ...
- 关于C++的子类指针指向父类
基类指针引用派生类对象 用基类指针引用一个派生类对象,由于派生类对象也是基类的对象,所以这种引用是安全的; 但是只能引用基类成员. 若试图通过基类指针引用那些只在派生类中才有的成员,编译器会报告语法错 ...
- c++ 动态判断基类指针指向的子类类型(typeid)
我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...
- C++析构函数的自动调用(用于父类指针指向子类对象,内存泄漏问题)
class A {public:A() { printf("A \n"); }~A() { printf(" ~A \n"); } // 这里不管写不写virt ...
- go语言笔记——切片底层本质是共享数组内存!!!绝对不要用指针指向 slice切片本身已经是一个引用类型就是指针
切片 切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型) ...
- 父类指针指向子类内存,为什么当父类的成员函数不加virtual时,访问的还是父类的成员函数,而不是子类同名的成员函数
我认为是这样,类的成员函数都在代码区,不同的类的成员函数在代码区有自己的类名称空间限制,类的虚函数在虚函数表中,程序执行的时候,是先在虚函数表中找该成员函数,如果没有找到,就去该类在代码区的成员函数中 ...
- foreach() 中用指针指向数组元素,循环结束后最好销毁指针
之前发过一次微博,今天又遇到这个问题,并且再次犯错,于是决定再加深一下. 就举php.net里的一个例子吧 $a = array('abe','ben','cam'); foreach ($a as ...
随机推荐
- BZOJ 3130 [Sdoi2013]费用流 ——网络流
[题目分析] 很容易想到,可以把P放在流量最大的边上的时候最优. 所以二分网络流,判断什么时候可以达到最大流. 流量不一定是整数,所以需要实数二分,整数是会WA的. [代码] #include < ...
- 【jquery创建元素添加元素】
使用jquery创建新元素的方法为:$(html标签),例如 $("<p></p>")创建了一个段落.注意此时只是创建了对象,尚未添加到文档节点中去:以下四 ...
- 栅格网络流(cogs 750)
[问题描述] Bob 觉得一般图的最大流问题太难了,他不知道如何解决,于是他想尝试一个简单点的:栅格网络中的最大流问题,这个虽说简单了一点,但对 Bob 来说依旧太难,现在他有个麻烦需要你帮忙:给你一 ...
- Aragorn's Story(hdu3966)
题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...
- POJ 3585 Accumulation Degree
二次扫描与换根法 用于解决无根树,对于每一个节点作为根时都要统计 做法: 1.先以任意一个节点为根,做树形DP,保存每个节点的DP值 2.然后自上而下dfs,对于每个节点考虑以他为根的最大值 #inc ...
- ElasticSearch API 之 UPDATE
ES本身是一个倾向于查询检索的框架,对于更新的操作,太过频繁总归不好的. 阅读本篇后,你可以使用Script对所有的文档执行更新操作,也可以使用doc对部分文档执行更新,也可以使用upsert对不存在 ...
- 标准C程序设计七---20
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- Oracle 实现 一个关键字 匹配多个 字段
有这么一个需求,满足只有一个输入框的条件下,支持不同数据列的搜索结果. 说白了,就是这个 输入框 既可以用来 搜索姓名,也可以搜索 年龄,地址等. 分析: 一般情况下,我们的一个输入框对应 数据库 ...
- Currency Exchange(最短路)
poj—— 1860 Currency Exchange Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 29851 Ac ...
- linux shell简单实现数据库自动备份
以centos系统为例,实现数据库自动备份.1.写一个shell: 12 #! /bin/bashmysqldump -cp --user=root --password='123' dbName | ...