[vox-tech] Memory addressing?
Chanoch (Ken) Bloom
kbloom at gmail.com
Tue Jun 22 09:46:59 PDT 2010
On Tue, Jun 22, 2010 at 09:11:44AM -0700, Brian Lavender wrote:
> Can someone confirm what is correct?
>
> Tim and I were discussing memory addressing at Crepeville last night
> and we had a disagreement about how memory is addressable. I say that
> on today's common intel i386 32 bit architecture (in case you are one of
> those souls who builds your hardware from scratch), that memory is byte
> (octet) addressable. You can load a byte from memory into the lower 8
> bits of a register. Tim says that memory is only addressable on 32 bit
> word boundaries.
>
> Say you look at memory in bits and then on the left is the memory
> address.
>
> I say that memory is normally byte addressable and the addressing
> corresponds to byte (octet) boundaries.
>
> Address bits
> 0 0 7 15 23 31
> 3 0 7 15 23 31
> 7 0 7 15 23 31
> 11 0 7 15 23 31
> 15 0 7 15 23 31
>
> Tim says that memory is only 32 bit word addressable
>
> Address bits
> 0 0 7 15 23 31
> 1 0 7 15 23 31
> 2 0 7 15 23 31
> 3 0 7 15 23 31
> 4 0 7 15 23 31
Consider the following program. The fact that you can get pointers to
arbitrary characers should be enough proof that the architecture is
byte addressable. (I don't know of any modern architectures that aren't
byte addressable, though MIPS takes some shortcuts in its various jump
instructions because the instructions have to be word-aligned.)
Now what can happen is that the computer crashes when dereferencing
the integer pointer, complaining that the access is unaligned -- the
addresses would still refer to individual bytes, but the computer
would crash if the two least significant bits were nonzero. MIPS
behaves this way, but since the following program works, you can see
that Intel doesn't even require word-aligned integer accesses.
(word-aligned integer accesses may be faster, but they don't require
special instructions to perform them).
And just to prove that the compiler isn't performing any funny
business, I included an assembly dump from this program.
#include <stdio.h>
int main(int argc, char** argv){
char* mystring="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int theint= *((int*)(mystring+1));
printf("%x\n",theint);
}
$ ./test | xxd -r -p
EDCB
AMD64 assembly language:
.file "test.c"
.section .rodata
.LC0:
.string "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
.LC1:
.string "%x\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movq $.LC0, -16(%rbp)
movq -16(%rbp), %rax
addq $1, %rax ; we're adding 1 to an address
; for one character
movl (%rax), %eax ; and here we're dereferencing it
; successfully
movl %eax, -4(%rbp)
movl $.LC1, %eax
movl -4(%rbp), %edx
movl %edx, %esi
movq %rax, %rdi
movl $0, %eax
call printf
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.4.4-5) 4.4.4"
.section .note.GNU-stack,"", at progbits
Intel 32-bit x86 assembly language:
.file "test.c"
.section .rodata
.LC0:
.string "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
.LC1:
.string "%x\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $.LC0, 24(%esp)
movl 24(%esp), %eax
addl $1, %eax ; we're adding 1 to an address
; for one character
movl (%eax), %eax ; and we're loading from that
; address without a special instruction
movl %eax, 28(%esp)
movl $.LC1, %eax
movl 28(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
leave
ret
.size main, .-main
.ident "GCC: (Debian 4.4.4-5) 4.4.4"
.section .note.GNU-stack,"", at progbits
--
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/
More information about the vox-tech
mailing list