X86-64數(shù)據(jù)移動指令

  • 入棧和出棧指令
  • 移動指令

移動指令

mov S D

  • movb
  • movw
  • movl
  • movq
    當(dāng)源操作數(shù)是常數(shù)時(shí),這個(gè)常數(shù)必須是32位的補(bǔ)碼進(jìn)行表示的,而且移動時(shí)將會進(jìn)行64位的符號拓展;
  • movabsq
    源操作數(shù)可以是任意的64位常數(shù)值,有符號的或者無符號的;目標(biāo)操作數(shù)必須是寄存器類型;

規(guī)定

  • 源操作數(shù)的值可以是常數(shù)值、寄存器類型、內(nèi)存引用類型;
  • 目標(biāo)操作數(shù)可以是寄存器類型、內(nèi)存引用類型,不能是常數(shù)值;
  • 源操作數(shù)和目標(biāo)操作數(shù)不能同時(shí)都是內(nèi)存引用類型,即從一個(gè)內(nèi)存位置復(fù)制一個(gè)值到另一個(gè)內(nèi)存位置需要兩個(gè)指令:首先,將源值加載進(jìn)某個(gè)寄存器,然后將這個(gè)寄存器的值寫入到目標(biāo)內(nèi)存地址處;

移動指令的5種可能的源操作數(shù)跟目標(biāo)操作數(shù)組合

  • 常數(shù), 寄存器
  • 常數(shù), 內(nèi)存引用
  • 寄存器, 寄存器
  • 寄存器, 內(nèi)存引用
  • 內(nèi)存引用, 寄存器

例外

當(dāng)movl指令的目標(biāo)操作數(shù)是寄存器類型時(shí),會將寄存器的高4個(gè)字節(jié)位全設(shè)置為0

舉例

  1. mov指令的副作用

    移動指令的副作用.png

  2. movb字節(jié)移動指令的副作用

    字節(jié)移動指令的副作用.png

3.2 熟悉下移動指令

movl %eax, (%rsp) #32->64,小到大,類型由小丁;
movw (%rax), %dx #64->32,大到小,類型由小定;
movb $0xFF, %bl #8->8
movb (%rsp, %rdx, 4), %dl #64->8,大到小,類型由小定;
movq (%rdx), %rax #64->64
movw %dx, (%rax) #16->64,小到大,類型由小定

3.3 指出下列移動指令中的錯(cuò)誤

movb $0xF, (%ebx) #8->32,%ebx不能作為地址寄存器;
movl %rax, (%rsp) #64->64,movl改為movq;
movw (%rax),4(%rsp) #64->64,不能兩個(gè)操作數(shù)都是內(nèi)存引用類型;
movb %al,%sl # %sl寄存器不存在
movq %rax,$0x123 #常數(shù)不能作為目的操作數(shù);
movl %eax,%dx #32->16,movl改為movw;
movb %si, 8(%rbp) #16->64,movb改為movw;
  1. 4 Assume variables sp and dp are declared with types
src_t *sp;
dest_t *dp;

where src_t and dest_t are data types declared with typedef. We wish to use the appropriate pair of data movement instructions to implement the operation
*dp = (dest_t) *sp;

Assume that the values of sp and dp are stored in registers %rdi and %rsi, respectively. For each entry in the table, show the two instructions that implement the specified data movement.

The first instruction in the sequence should read from memory, do the appropriate conversion, and set the appropriate portion of register %rax. The second instruction should then write the appropriate portion of %rax to memory. In both cases, the portions may be %rax, %eax, %ax, or %al, and they may differ from one another.

Recall that when performing a cast that involves both a size change and a change of “signedness” in C, the operation should change the size first.

1. long->long # 64->64
movq (%rdi), %rax
movq rax%, (%rsi)
2. char->int #有符號8->有符號32,有符號拓展
movsbl (%rdi), %eax
movl %eax, (%rsi)
3. char->unsigned #有符號8->無符號32,有符號拓展
movsbl (%rdi), %eax
movl %eax, (%rsi)
4. unsigned char->long #無符號8->有符號64,無符號拓展
mobzbq (%rdi), %rax
movl %rax, (%rsi)
5. int->char #有符號32->有符號8,截?cái)嗵幚?movl (%rdi), %eax
movb %al, (%rsi)
6. unsigned->unsigned char #無符號32->無符號8,截?cái)嗵幚?movl (%rdi), %eax
movb %al, (%rsi)
7. char->short #有符號8->有符號16
movsbw (%rdi), %ax
movw %ax, (%rsi)

3.5 You are given the following information. A function with prototype

void decode1(long *xp, long *yp, long *zp);
# xp in %rdi, yp in %rsi, zp in %rdx

is compiled into assembly code, yielding the following:

decode1:
  movq    (%rdi), %r8
  movq    (%rsi), %rcx
  movq    (%rdx), %rax
  movq    %r8, (%rsi)
  movq    %rcx, (%rdx)
  movq    %rax, (%rdi)
  ret

Parameters xp, yp, and zp are stored in registers %rdi, %rsi, and %rdx, respectively.
Write C code for decode1 that will have an effect equivalent to the assembly code shown.
解答:

void decode1(long *xp, long *yp, long *zp) {
    long x = *xp;
    long y = *yp;
    long z = *zp;
    *yp = x;
    *zp = y;
    *xp = z;
    return z;
}

入棧和出棧指令

  • pushq S
  • popq D

入棧指令

pushq %rbp
等價(jià)于

subq $8, %rsp
movq %rbp, (%rsp)

出棧指令

popq %rax
等價(jià)于

movq (%rsp), %rax
addq $8, %rsp
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容