Assembly Endianness-何时订购?

Assembly Endianness-何时订购?,assembly,endianness,Assembly,Endianness,我得到了endianness的一般概念,但我对endianness如何以及何时出现的机制有点模糊。我有一个英特尔x64的组装示例: section .data newline_char: db 10 codes: db '0123456789abcdef' section .text global _start print_newline: mov rax, 1 ; 'write' syscall identifier mov rdi, 1

我得到了endianness的一般概念,但我对endianness如何以及何时出现的机制有点模糊。我有一个英特尔x64的组装示例:

section .data

newline_char: db 10
codes: db '0123456789abcdef'

section .text
global _start

print_newline:
    mov rax, 1          ; 'write' syscall identifier
    mov rdi, 1          ; 'stdout' file descriptor
    mov rsi, newline_char   ; starting address of data
    mov rdx, 1          ; number of bytes to write
    syscall
      ret

print_hex:
    mov rax, rdi        ; move input (rdi) to rax
    mov rdi, 1          ; 'stdout' file descriptor
    mov rdx, 1          ; number of bytes to write
    mov rcx, 64         ; bit/position counter

iterate:
    push    rax         ; save input, rax altered later
    sub rcx, 4          ; every iteration shifts 4 fewer
    sar rax, cl         ; shift rax 'cl' times (cl is lowest byte of rcx)
    and rax, 0xf        ; 'AND' rax with 0xf to preserve lowest 4 bits
    lea rsi, [codes + rax]  ; add value of rax to address of codes

    mov rax, 1          ; 'write' syscall identifier (prepare to write)
    push    rcx         ; 'write' syscall alters rcx (counter) (rcx caller saved)

    syscall

    pop rcx         ; restore counter
    pop rax         ; restore original input

    test    rcx, rcx        ; rcx & rcx -> (set flags)
    jnz iterate         ; if not zero, load 'iterate' to RIP

      ret


section .data
demo1: dq 0x1122334455667788
demo2: db 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80

section .text

_start:
    mov rdi, [demo1]
    call    print_hex
    call    print_newline

    mov rdi, [demo2]
    call    print_hex
    call    print_newline

    mov rax, 60
    xor rdi, rdi
    syscall 
当我按原样运行时,我得到
1122334455667788
80706050430010

所以,在这一点上我有点困惑,因为我认为
88
80
都会存储在第一个内存地址中

在这一点上,我认为如果我保持标记值不变,并将64位
rax
寄存器更改为32位
eax
寄存器,我将得到
11223344
80706050
。但是,我得到了
11223344
40302010

如果我仍然在
demo2
中使用
db
存储相同的8个字节,我应该先获得相同的最低有效字节吗


还有,为什么
demo1
不按相反的顺序打印?endianness是否只适用于单个存储的字节?

您使用的汇编程序也知道您的处理器是little endian。因此,当您使用
dq
时,它知道88是小头,应该首先存储。当您使用
db
时,它不再有用,现在字节顺序很重要,10是小的结束。当您使用eax而不是rax时,寄存器不再能够表示大端的四个字节,它们就消失了。没有发生任何特殊情况。因此,如果
dq
在小端存储
88
,为什么从该内存地址开始打印不会产生
88776655
?因为您的代码专门以大端打印?你从最重要的半字节开始。你的打印十六进制代码没有被破坏,它知道需要先打印大头。因此,SAR在循环中第一次移动60位。Endity在该代码中不起任何作用。如果您将其更改为
eax
,您应该获得demo1
55667788
,而不是
11223344
???(由于
demo1
处的内存内容是
8877665544332211
,而
demo2
处的内存内容是
102030050607080
(从汇编程序中检查列表文件,并将其加载到调试器中,在获取后检查内存视图与
rax/eax
的内容)。(不要依赖于
print
进行调试,只要找到适合您的好调试器(
gdb
edb调试器
是两个完全不同的选项,其中一个应该适合您)。