把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 ...
随机推荐
- 性能测试之五--webservices接口测试
下面我们进行webservices接口的讲解,包括脚本生成,参数化和关联. 以天气预报的接口为例,接口地址为: http://ws.webxml.com.cn/WebServices/WeatherW ...
- PAT天梯赛练习题——L3-004. 肿瘤诊断(三维连通块并查集)
L3-004. 肿瘤诊断 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在诊断肿瘤疾病时,计算肿瘤体积是很重要的一环.给定病灶 ...
- 雅礼培训 Problem B 【图论 + 贪心】
题意 A和B在树上轮流选点,记A的联通块个数为\(x\),B的联通块个数为\(y\) A使\(x - y\)最大,B使\(x - y\) 二人采取最优策略,求\(x-y\) 题解 树联通块个数 = 点 ...
- ORACLE无法删除当前连接用户
今天在做Oracle数据库是遇到ORACLE无法删除当前连接用户 ,经查找可用如下方法解决 . 在Oracle中删除用户时提示:ORACLE无法删除当前连接用户 可以用以下语句 Sql代码 ...
- C++ string 类中的 assign()函数
C++ string 类的成员函数,用于拷贝.赋值操作,它们允许我们顺次地把一个 string 对象的部分内容拷贝到另一个 string 对象上. 函数原型 string &operator= ...
- MVC 上传文件的方法
这两天又开始研究MVC了,期间断断续续已经搞了好久了,可是都没坚持下来.囧!这次一定坚持搞出来一个名堂. 废话少说,直接上代码. 前台引擎采用Razor @model System.Web.HttpP ...
- localStorage增删改查
/** * 设置 本地缓存 */ export function setStorage(key, obj) { if (typeof obj === 'string') { localStorage. ...
- BestCoder Round #25 1002 Harry And Magic Box [dp]
传送门 Harry And Magic Box Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- Scrapy学习-8-ItemLoader
ItemLoader使用 作用 方便管理维护重用xpath或css规则 实例 itemloader+图片处理 # items.py import scrapy from scrapy.loader ...
- AttributeError: module 're' has no attribute 'search'
命名py脚本时,不要与python预留字,模块名等相同,即Python文件名不要使用Python系统库的名字,就是因为使用了Python系统库的名字,所以在编译的时候才会产生.pyc文件.正常的Pyt ...