How many bytes are there in one address? [duplicate]

痴心易碎 提交于 2020-07-23 06:53:22

问题


On a 64bit machine, we know that an address is 8 bytes. However, I am not entirely clear how many bytes of information is in one address. Does every byte in virtual memory have an address? Or does every 64 bits in memory have an address? Or does it depend on the architecture? If it depends on the architecture, then how should I find out?


回答1:


Your question is related to this one.

Or does it depend on the architecture?

Yes. It depends on the architecture:

For most CPUs one address represents 8 bits.

Each byte in the memory has an individual address.

The TMS320 DSP is an example for a CPU where one address represents 16 bits.

This means that each 16-bit word (uint16) in the memory has an individual address.

There are also computers (many of them historic) where each address represents 12, 13, 14, 16, 24 or 36 bits (and maybe even more) ...

(Unfortunately, I don't know an example for a CPU using 64-bit addresses not using 8 bits per address but I'm quite sure such CPUs also exist.)

Then there are memory types where not all addresses exist. This may look the following way:

Addresses which are divisible by 4 represent 32 bits of information; other addresses cannot be used - which means that these addresses represent no information at all.

So the "average" over the addresses is 8 bits but there is no address that represents 8 bits.

Typically you see such a behavior in a computer where two different types of memory are installed and one type allows both 8- and 32-bit access while the other type only allows 32-bit access.

And this is often the case for the memory of peripheral devices - for example the memory of the Ethernet controller in some microcontrollers.

Is far as I remember correctly, I have seen a PCI SCSI controller for PCs that also showed this behavior. Install that SCSI controller into your 64-bit computer and your computer contains some range of addresses where 25% of all addresses represent 32 bits of data and 75% of all addresses don't represent any data at all.

I've also seen CPUs designed by students of universities where the "commercial original" allows 8- and 32-bit access to the memory but the student's replica allows only 32-bit access. In this case the whole address range shows this behavior.

By the way:

On a 64bit machine, we know that an address is 8 bytes.

Even this is not necessarily true:

As far as I know, an x86-64 CPU uses only 48-bit addresses. Therefore it would be possible for a compiler manufacturer to store each address in only 6 bytes of memory.

And of course CPU cores for embedded devices could be designed to use a subset of the x86-64 instruction set but registers that typically hold an address (such as rsp) are only 48 bits wide.




回答2:


In C, char is the smallest addressable unit. (And usually maps to the smallest asm addressable unit, but there's no guarantee of that1.) CHAR_BIT from limits.h tells you how many bits it has. That's usually 8 but historically there have been machines with non-power-of-2 byte and word sizes.

In asm, most modern ISAs are byte-addressable, but modern DSPs are sometimes word-addressable because the only code they care about running is code that processes integer or float data, not strings.

If it depends on the architecture, then how should I find out?

This is something you find out from the ISA manual, along with other basics like names of registers and their widths. It's an inherent property of the machine language.


Footnote 1:

You could image a weird hypothetical ISA that was byte addressable, but where a byte store might be implemented as a non-atomic read-modify-write of the containing (32-bit) word. Either in hardware (extremely unusual) or in software (which has actually happened).

For example, the first couple versions of DEC Alpha AXP (a RISC ISA from the 90s aggressively designed for high performance and 64-bit) had byte addressable memory, but the narrowest load/store was 32-bit.

So every byte had its own address, but there were no hardware instructions to modify a single byte. If C implementations at the time used CHAR_BIT=8, they would have to emulate char assignment with a software load / merge / store, unless they knew it was a char object with padding (like a local or global) where they could just overwrite the padding.

A modern C11 implementation would have to use CHAR_BIT=32 or use a slow LL/SC retry loop to atomically replace a byte when dereferencing a char* as an lvalue, because C11 introduced a memory model that doesn't allow inventing writes (like read and later rewrite the same data) that don't happen in the C abstract machine. That could break code where separate threads write adjacent data. See C++ memory model and race conditions on char arrays (the C11 memory model matches C++11 in this regard).

See also Can modern x86 hardware not store a single byte to memory? for more details, not just x86.

Later models of Alpha introduced byte and halfword load/store instructions, so compilers could use those to implement a valid C11 implementation with one-byte char.




回答3:


Peter &ch[1] doesnt work, but ch is a char pointer so you can move on it adding +1 to get next char in array. As the proove:

cout<<sizeof(char)<<endl;
char ch[3]={55,33,70};
char *chp1=ch;
cout<<chp1<<" "<<&(chp1)<<" ";
char *chp2=ch+1;
cout<<chp2<<" "<<&(chp2)<<" ";
char *chp3=ch+2;
cout<<chp3<<" "<<&(chp3)<<endl;
return 0;

Dec 55 is 7 in char 33 is ! 70 is F https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html They are being couted as 7!F, !F, F because arrays of chars are couted up to blank space. So as you can see pointers point to next chars of above array. Output: i.stack.imgur.com/pBot5.jpg

cout<<sizeof(char)<<endl;
char ch[3]={55,33,70};
char *chp1=ch;
cout <<ch[0]<<" "<< (void*)(&ch[0])<<" "<<ch[1]<<" "<<(void*)(&ch[1])<<" "<<ch[2]<<" "<<(void*)(&ch[2])<<endl;



回答4:


You can check how addresses change by changing variable.

cout<<sizeof(char)<<endl;
char ch[3];
cout<<ch[0]<<" "<<std::hex<< (long)(char*)(&ch[0])<<" "<<ch[1]<<" "<<(long)(char*)(&ch[1])<<" "<<ch[2]<<" "<<(long)(char*)(&ch[2])<<endl;


来源:https://stackoverflow.com/questions/56717135/how-many-bytes-are-there-in-one-address

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!