- 入棧和出棧指令
- 移動指令
移動指令
mov S D
movbmovwmovl-
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
舉例
-
mov指令的副作用
移動指令的副作用.png -
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;
- 4 Assume variables
spanddpare 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 Spopq D
入棧指令
pushq %rbp
等價(jià)于
subq $8, %rsp
movq %rbp, (%rsp)
出棧指令
popq %rax
等價(jià)于
movq (%rsp), %rax
addq $8, %rsp

