Chapter 12
Page 258
-
GAS LISTING register_change.s page 1 1 # register_change.s 2 # Some instructions to illustrate machine code. 3 .intel_syntax noprefix 4 .text 5 .globl main 6 .type main, @function 7 main: 8 0000 55 push rbp # save caller's frame pointer 9 0001 4889E5 mov rbp, rsp # establish our frame pointer 10 11 0004 89C1 mov ecx, eax # 32 bits, low reg codes 12 0006 89DA mov edx, ebx # highest reg codes 13 0008 6689D3 mov bx, dx # 16 bits 14 000b 88D3 mov bl, dl # 8 bits 15 000d 4589D3 mov r11d, r10d # 32 bits, 64-bit register 16 0010 4889DA mov rdx, rbx # 64 bits 17 18 0013 B8000000 mov eax, 0 # return 0 to os 18 00 19 0018 4889EC mov rsp, rbp # restore stack pointer 20 001b 5D pop rbp # and frame pointer 21 001c C3 ret # back to caller
Let’s look at the code for
mov r11d, r10d
. We can tell from the manual and several othermov
instructions that the opcode is89
. It’s prefaced with a REX byte,01000101
. The W bit is0
, showing that the data being moved is not 64 bits but the default 32 bits. TheR
andB
bits in the REX byte are both1
which are used as the high-order bit to specify the registers. The ModR/B byte is11010011
. Figure 2-5 in the xxx version of the Intel manual shows that the first two bits,11
, specify a register-to-register move. The next three bits combine with theR
bit in the REX byte to give1010
, which Table 12-2 in our book shows isr10
. The last three bits combine with theB
bit in the REX byte to give1011
, which specifiesr11
. -
GAS LISTING regToMemory.s page 1 1 # regToMemory.s 2 # Some instructions to illustrate machine code. 3 .intel_syntax noprefix 4 .text 5 .globl main 6 .type main, @function 7 main: 8 0000 55 push rbp # save caller's frame pointer 9 0001 4889E5 mov rbp, rsp # establish our frame pointer 10 0004 4883EC30 sub rsp, 48 # local variables 11 12 0008 48C7C105 mov rcx, 5 # for indexing 12 000000 13 000f 8B4500 mov eax, [rbp] # indirect 14 0012 8945D0 mov -48[rbp], eax # indirect + offset 15 0015 89440DD0 mov -48[rbp+rcx], eax # indirect + offset and index 16 0019 89448DD0 mov -48[rbp+4*rcx], eax # and scaled index 17 18 001d B8000000 mov eax, 0 # return 0 to os 18 00 19 0022 4889EC mov rsp, rbp # restore stack pointer 20 0025 5D pop rbp # and frame pointer 21 0026 C3 ret # back to caller
Look at the three instructions where we reversed the order of the source and destination thus moving from a register to memory. Comparing the machine code with the respective instructions in Listing 12-3, we see that the only thing that has chaned is the opcode has changed from
8B
to89
. -
GAS LISTING constToMemory.s page 1 1 # constToMemory.s 2 # Some instructions to illustrate machine code. 3 .intel_syntax noprefix 4 .text 5 .globl main 6 .type main, @function 7 main: 8 0000 55 push rbp # save caller's frame pointer 9 0001 4889E5 mov rbp, rsp # establish our frame pointer 10 0004 4883EC30 sub rsp, 48 # local variables 11 12 0008 48C7C105 mov rcx, 5 # for indexing 12 000000 13 000f 8B4500 mov eax, [rbp] # indirect 14 0012 C745D034 mov dword ptr -48[rbp], 0x12000034 # indirect + offset 14 000012 15 0019 C7440D30 mov dword ptr -48[rbp+rcx], 0x56000078 # indirect + offset and index 15 78000056 16 0021 C7448DD0 mov dword ptr -48[rbp+4*rcx], 0x91000023 # and scaled index 16 23000091 17 18 0029 B8000000 mov eax, 0 # return 0 to os 18 00 19 002e 4889EC mov rsp, rbp # restore stack pointer 20 0031 5D pop rbp # and frame pointer 21 0032 C3 ret # back to caller
Let’s look at the
mov dword ptr -48[rbp+4*rcx], 0x91000023
instruction. The opcode is0xc7
. That’s followed by a ModR/M byte, an SIB byte, an offset byte, and four bytes for the constant.The
0x44
value for the ModR/B byte means that it is followed by an SIB byte with a one-byte offset. The SIB byte,10 001 101
, specifies a scale factor of 4,rcx
is the index register, andrbp
is the base register. The offset is stored as a one-byte, two’s complement value:0xd0
= -4810. Notice that the constant,0x91000023
, is stored in little endian order,0x23000091
.