现在的处理器大多是 32 位或 64 位。这意味着它们处理的指令具有这个大小。
我们经常听说 32 位操作系统的 RAM 限制为 4GB=(2^32 位),因为 RAM 地址的长度需要保存在 32 位内。
但事实上,当我们查看指令的外观时,您通常需要不到 32 位来加载一个字。
以 x86mov指令为例,您有一个操作码、一个源地址和一个目标地址。
我的问题是,我们如何才能从 32 位长的地址加载某些内容?
我们是否总是需要在内存中某个位置有一个指向该地址的指针,该位置具有可在指令中使用的较小地址?
谢谢
我正在努力成为“一个真正的人”,也就是从 C++ 转向 C。指针和 malloc 有时会让人感到困惑。我正在使用没有任何标志的 gcc,64 位 Linux。
所以我的第一个问题是:
int* c;
int* d;
void* shared = malloc(sizeof(int)*2);
c = shared;
d = shared + sizeof(int);
*c = 123;
*d = 321;
printf("c: %p, *c: %i\n", (void*)c, *c);
printf("d: %p, *d: %i\n", (void*)d, *d);
printf("sizeof(c): %lu, sizeof(d): %lu\n", sizeof(c), sizeof(d));
Run Code Online (Sandbox Code Playgroud)
输出:c:0x1c97050,*c:123 d:0x1c97054,*d:321 sizeof(c):8,sizeof(d):8
将两个内存地址转换为十进制并检查它们的差异,得到 4。这意味着它们在内存中彼此相距 4 个字节?这意味着 int 用 4 个字节表示,sizeof(int) = 4。
但是由于 64 位内存,一个指针(我猜是任何类型的指针,但在我们的例子中是一个 int)是用 8 个字节表示的?这意味着我犯了一个错误,只分配了 4 个字节而不是所需的 8 个字节(int 而不是 int*)。
但为什么我没有丢失任何数据呢?纯粹是巧合/运气?
问题是找到最后一个元素.它运行良好整数类型.使用Int类型溢出,但是当我尝试Int64时,似乎垃圾收集器停止工作.
module Main (main) where
import Data.Int
import System.Environment
getNum :: Int -> Int64
merge [] s2 = s2
merge s1 [] = s1
merge (s1:s1s) (s2:s2s)
| s1 < s2 = s1 : (merge s1s (s2:s2s))
| s1 > s2 = s2 : (merge (s1:s1s) s2s)
| otherwise = s1 : (merge s1s s2s)
scaleStreams scale = map $ (*) scale
getNum n = s_3_56!!n
where s_3_56 = 1:(merge (scaleStreams 2 s_3_56)
(merge (scaleStreams 3 s_3_56)
(scaleStreams 5 s_3_56 …Run Code Online (Sandbox Code Playgroud) 使用VS 2003生成的用于生成32位二进制文件的代码在没有单个警告的情况下构建.
相同的代码,没有单一的代码更改,编译和链接成功使用Visual Studio 2010编译器生成64位二进制BUT与下面的警告列表.
所以,我的问题是,下面列表中的任何警告都是运行时的问题吗?
pcd.c(248) : warning C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
pcd.c(377) : warning C4244: '=' : conversion from 'uintptr_t' to 'ULONG', possible loss of data
pcd.c(236) : warning C4100: 'argv' : unreferenced formal parameter
i.c(183) : warning C4100: 'lpReserved' : unreferenced formal parameter
api.c(506) : warning C4996: 'stricmp': The POSIX name for this item is deprecated. Instead, use …Run Code Online (Sandbox Code Playgroud) ong中的OgUtil.pas我想移植到64位
Delphi 64位不允许使用带有pascal的ASM我可以将此函数转换为使用delphi 64位工作
function LockFile(Handle : THandle;
FileOffsetLow, FileOffsetHigh,
LockCountLow, LockCountHigh : Word) : Boolean;
var
Error : Word;
begin
asm
mov ax,$5C00
mov bx,Handle
mov cx,FileOffsetHigh
mov dx,FileOffsetLow
mov si,LockCountHigh
mov di,LockCountLow
int $21
jc @@001
xor ax,ax
@@001:
mov Error,ax
end;
Result := Error = 0;
end;
Run Code Online (Sandbox Code Playgroud)
可以将此代码转换为完全pascal
function UnlockFile(Handle : THandle;
FileOffsetLow, FileOffsetHigh,
UnLockCountLow, UnLockCountHigh : Word) : Boolean;
var
Error : Word;
begin
asm
mov ax, $5C01
mov bx,Handle
mov cx,FileOffsetHigh
mov dx,FileOffsetLow
mov si,UnLockCountHigh …Run Code Online (Sandbox Code Playgroud) 我有一个函数返回record结果.我需要将它传递给另一种方法Pointer.它适用于32位模式,但Invalid type cast在64位模式下会引发错误.我该如何解决?
我试图寻找已知的解决方案,但发现只有record到TObject转换方法:无效的类型转换:转换记录TObject的64位平台
aTList.Add(Pointer(aRecord)); // aRecord is a result of the function
Run Code Online (Sandbox Code Playgroud) 这可能是一个非常愚蠢的问题:
我们正在开发Solaris系统.
32位和64位的代码本身有什么不同吗?或者它更像是头文件的问题?
任何人都可以给我一个64位的简单hello-username示例?
这可能是一个菜鸟问题..但这真让我感到困惑..
下面是一些示例代码
void main() {
int a = 300;
char *ptr = &a;
int *intptr = &a;
printf("%d\n %d\n", *ptr, *intptr);
}
Run Code Online (Sandbox Code Playgroud)
产量:
44
300
根据我的理解,为什么解除引用*ptr打印44是由于char指针是一个字节的事实,所以它只从int的地址读取8位...
但是这个问题:指针的大小是多少?状态Regardless of what data type they are pointing to, they have fixed size
我错过了一些东西.为什么解引用char指针打印44,如果指针大小相同?
试图将一些代码从32位delphi移植到64.编译后我得到一个访问违规在64位补丁的这一行(在32上正常工作)
PByte = ^Byte;
function TyDecoder.findCRLF(pStart,pEnd: PByte): PByte;
begin
while (Not (((pStart^=13) and (pByte(Integer(pStart)+1)^=10)) or (pStart^=10))) and (Integer(pStart)<Integer(pEnd)) do Inc(pStart);
Result:=pStart;
end;
Run Code Online (Sandbox Code Playgroud)
以前有许多问题从D7移植到10.2东京但是通过将所有字符串声明更改为Ansistring来纠正这些问题.
我猜这可能与指针类型有关,现在是8而不是4.
难住了.
所以,真正的交易是我在本网站内外进行了大量研究,没有这样的问题或解决方案可以帮助我.
我正在学习C编码.这不是什么大问题,因为我非常了解Python和C#(Unity).问题是我正在尝试在Python上做我以前做过的应用程序,但我遇到了一个问题:我正在Debian 8虚拟机(Oracle的虚拟盒)上编译我的程序,如下所示:gcc -lm -m64 -o file.exe file.c.当我回到我的Windows 10机器(非虚拟)时,会发现我正在尝试运行的程序是一个不受支持的程序的16位版本,并且它无法运行它.我真的研究了很多,并且可以找到一些东西,我做的女巫......但是没有任何改变......所以,我认为在联系GCC程序或我的脚本bhaskara.c时有错误(是的,它是一个bhaskara公式计算器):
#include <stdio.h>
#include <math.h>
float main(){
double a, b, c, x1, x2;
double delta;
double d, e;
printf("NOTE: If the numbers are integers, use .0 at the end(eg. 1 = 1.0)\n");
printf("A = ");
scanf("%f", &a);
printf("B = ");
scanf("%f", &b);
printf("C = ");
scanf("%f", &c);
d = b*b;
e = (d + 4*a*c);
delta = sqrt(e);
printf("Delta = %f\n", delta);
x1 = (-b + delta)/2;
printf("X1 = %f\n", …Run Code Online (Sandbox Code Playgroud) 我正在编写一个程序,将二进制值的十六进制表示转换为常规字符串.因此十六进制表示中的每个字符都将转换为字符串中的两个十六进制字符.这意味着结果将是两倍大小; 1字节的十六进制表示将需要字符串中的两个字节.
十六进制字符
0123456789 ;0x30 - 0x39
ABCDEF ;0x41 - 0x46
Run Code Online (Sandbox Code Playgroud)
例
0xF05C1E3A ;hex
4032568890 ;dec
Run Code Online (Sandbox Code Playgroud)
会成为
0x4630354331453341 ;hex
5057600944242766657 ;dec
Run Code Online (Sandbox Code Playgroud)
题?
是否有任何优雅/替代(/有趣)方法在这些状态之间进行转换,而不是查找表,(按位运算,移位,模数等)? 我不是在寻找库中的函数,而是如何实现/应该如何实现.有任何想法吗?
我试图通过它的ID获取子窗口的句柄,但要做到这一点我必须双重转换ID,否则它将无法正常工作.还有其他方法吗?我错过了什么?
WINAPI x64 C++
码:
#define BASE_ID 100
UINT8 i = 1;
CreateWindow(... (HMENU)BASE_ID + i, ...)
//later in code
HWND hWnd = GetDlgItem(hParent, BASE_ID + i); // This won't work (Returns null handle)
HWND hWnd = GetDlgItem(hParent, (int)((HMENU)BASE_ID + i)); //Works but I get compiler warning
Run Code Online (Sandbox Code Playgroud)