X86汇编问答

1.地址总线,数据总线,控制总线在哪里,它们有什么作用?
答:它们都是cpu连接外部组件的线路。
地址总线:
地址总线AB用于传送CPU发出的地址信息,是单向的。传送地址信息的目的是指明与CPU交换信息的内存单元或I/O设备。逻辑概念可以理解为外部件连接变址寄存器的数字电路。
数据总线:
数据总线DB用来传送数据信息,是双向的。CPU既可通过DB从内存或输入设备读入数据,又可通过DB将内部数据送至内存或输出设备。逻辑概念可以理解为外部件连接数据寄存器的数字电路。
控制总线:
控制总线CB用来传送控制信号、时序信号和状态信息等。其中有的是CPU向内存或外部设备发出的信息,有的是内存或外部设备向CPU发出的信息。显然,CB中的每一条线的信息传送方向是一定的、单向的,但作为一个整体则是双向的。逻辑概念可以理解为外部件连接指令和标志位寄存器等。

2.1个CPU 的寻址能力为1MB,那么它的地址总线的宽度为多少?
答:宽度为20位。

3.在存储器中(内存),数据和程序以什么形式存放?
答:二进制

4.汇编语言中的指令和数据有区别吗?
答:汇编语言中使用的一些操作符和助记符,还包括一些伪指令(如assume,end)。用于告诉汇编如何进行汇编的指令,它既不控制机器的操作也不被汇编成机器代码,只能为汇编程序所识别并指导汇编如何进行。而数据只是单纯的某种进制数据表示和存储单元。

5.下面是一些简单的汇编指令和指令对应的功能:
MOV eax ,10
ADD eax ,10
MOV ebx ,eax

请写出下面每条汇编指令执行后相关寄存器中的值:
mov eax,123 eax:123

mov ebx ,eax ebx:123 eax:123

add eax,100 eax:223

add eax ,ebx eax:346 ebx:123

add ebx,eax ebx:469 eax:346
eip 寄存器能直接被修改吗? 哪些指令能够间接修改这个寄存器?

答:指令指针eip寄存器不能直接被修改,可以间接修改eip的有call,ret,jmp,jcc。

6.请将下面汇编语言中的指令和C 语言中的关键字按照功能连线。
不使用连线,对应如下:

MOV =(赋值语句)
CMP if
JMP goto
INC ++(自增运算)
DEC --(自减运算)
ADD +=

7.请列举标志寄存器的标志位,并阐述这些标志位在什么情况下会发生改变
答:状态标志位
CF carry flag 进位标志 当运算结果的最高有效位有进位或者借位时CF = 1,否则为0
ZF zero flag 零标志位 当运算结果为0时ZF=1,否则为0
SF sign flag 符号标志位 当运算结果最高位为1,SF=1,否则为0。
PF parity flag 奇偶标志位 当运算的结果最低八位中“1”的个数为零或者偶数时,PF=1,否则PF=0
OF overflow flag 溢出标志 当算术运算的结果又溢出,则OF=1,否则OF=0
AF auxiliary carry flag 辅助进位标志 运算时D3位(低半字节)有进位或者借位时AF=1,否则为零

控制标志位
DF direction flag 方向标志 存储器地址自动增加时为零,自动减少时为1
IF interrupt-enable flag 设置为1时,允许中断,为零则禁止中断
TF trap flag 设置TF=0时,处理器正常工作,为1时处理器单步执行指令

================
1.常用的寄存器都有哪些?
答:
8086(16位)14个:
ax bx cx dx (ah al bh bl ch cl dh dl)
si di sp bp
cs es ss ds
flags ip

32位16个:
eax ebx ecx edx (ah al bh bl ch cl dh dl)
esi edi esp ebp
ecs ees ess eds efs egs
eflags eip

2.通用寄存器:eax,ebx,ecx,edx,esi,edi,ebp,esp
简述上述存储器的作用
答:前缀均为Extra
eax 累加器(Accumulator),用累加器进行的操作可能需要更少时间。可用于乘、 除、输入/输出等操作,使用频率很高
ebx 基地址寄存器(Base Register)。它可作为存储器指针来使用
ecx (count)串操作、循环控制的计数器
edx 数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址
esi (Source Index):源变址寄存器。存储器指针、串指令中的源操作数指针
edi (destination index)目标变址寄存器。存储器指针、串指令中的目的操作数指针
ebp 基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据
esp 堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。

在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,
在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,
而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。

3.标志位都有哪些?
答:
状态标志位
CF carry flag 进位标志 当运算结果的最高有效位有进位或者借位时CF = 1,否则为0
ZF zero flag 零标志位 当运算结果为0时ZF=1,否则为0
SF sign flag 符号标志位 当运算结果最高位为1,SF=1,否则为0。
PF parity flag 奇偶标志位 当运算的结果最低八位中“1”的个数为零或者偶数时,PF=1,否则PF=0
OF overflow flag 溢出标志 当算术运算的结果又溢出,则OF=1,否则OF=0
AF auxiliary carry flag 辅助进位标志 运算时D3位(低半字节)有进位或者借位时AF=1,否则为零

控制标志位
DF direction flag 方向标志 存储器地址自动增加时为零,自动减少时为1
IF interrupt-enable flag 设置为1时,允许中断,为零则禁止中断
TF trap flag 设置TF=0时,处理器正常工作,为1时处理器单步执行指令

32位新增标志位
1、I/O特权标志IOPL(I/O Privilege Level)
I/O特权标志用两位二进制位来表示,也称为I/O特权级字段。该字段指定了要求执行I/O指令的特权级。
如果当前的特权级别在数值上小于等于IOPL的值,那么,该I/O指令可执行,否则将发生一个保护异常。
2、嵌套任务标志NT(Nested Task)
嵌套任务标志NT用来控制中断返回指令IRET的执行。具体规定如下:
(1)、当NT=0,用堆栈中保存的值恢复EFLAGS、CS和EIP,执行常规的中断返回操作;
(2)、当NT=1,通过任务转换实现中断返回。
3、重启动标志RF(Restart Flag)
重启动标志RF用来控制是否接受调试故障。规定:RF=0时,表示“接受”调试故障,否则拒绝之。
在成功执行完一条指令后,处理机把RF置为0,当接受到一个非调试故障时,处理机就把它置为1。
如果该标志的值为1,则表示处理机处于虚拟的8086方式下的工作状态,否则,处理机处于一般保护方式下的工作状态。

4、虚拟8086方式标志VM(Virtual 8086 Mode)

4.16位cpu和32位cpu中的寻址有什么区别?
答:16位cpu寻址,8086有20位地址总线,地址范围为1M字节单元,但cpu是16位的,因此需分段处理。32位寻址则其cpu的数据总线应是32位的,一次性可寻址范围为2的32次方,也就是4G了。

5.请说出你记得的常用指令
1)、数据传输指令

  1. 通用数据传送指令.
    MOV 传送字或字节.
    MOVSX 先符号扩展,再传送.
    MOVZX 先零扩展,再传送.
    PUSH 把字压入堆栈.
    POP 把字弹出堆栈.
    PUSHF
    PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
    POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
    PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
    POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
    BSWAP 交换32位寄存器里字节的顺序
    XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
    CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )
    XADD 先交换再累加.( 结果在第一个操作数里 )
    XLAT 字节查表转换.
    BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即 0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )
  2. 输入输出端口传送指令.
    IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
    OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )
    输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,其范围是 0-65535.
  3. 目的地址传送指令.
    LEA 装入有效地址.
    例: LEA DX,string ;把偏移地址存到DX.
    LDS 传送目标指针,把指针内容装入DS.
    例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
    LES 传送目标指针,把指针内容装入ES.
    例: LES DI,string ;把段地址:偏移地址存到ESDI.
    LFS 传送目标指针,把指针内容装入FS.
    例: LFS DI,string ;把段地址:偏移地址存到FSD.
    LGS 传送目标指针,把指针内容装入GS.
    例: LGS DI,string ;把段地址:偏移地址存到GSDI.
    LSS 传送目标指针,把指针内容装入SS.
    例: LSS DI,string ;把段地址:偏移地址存到SSDI.
  4. 标志传送指令.
    LAHF 标志寄存器传送,把标志装入AH.
    SAHF 标志寄存器传送,把AH内容装入标志寄存器.
    PUSHF 标志入栈.
    POPF 标志出栈.
    PUSHD 32位标志入栈.
    POPD 32位标志出栈.

2)、算术与逻辑运算指令
算术运算指令 :
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEC 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.
IMUL 整数乘法.
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.
IDIV 整数除法.
以上两条,结果回送:
商回送AL,余数回送AH, (字节运算);
或 商回送AX,余数回送DX, (字运算).

CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
AAD 除法的ASCII码调整.

逻辑运算指令 :
AND 与运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL

XOR 异或运算.
OR 或运算.
3)、串操作指令

DS:SI 源串段寄存器 :源串变址.
ESI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.
( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.
把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.
把源串中的元素(字或字节)逐一装入AL或AX中.
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.
是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.

4)、其它指令
SEG -------------------- 返回段地址
EQU(=) -------------------- 等值语句
PURGE -------------------- 解除语句
DUP -------------------- 操作数字段用复制操作符
SEGMENT,ENDS -------------------- 段定义指令
ASSUME -------------------- 段地址分配指令
ORG -------------------- 起始偏移地址设置指令
$ --------------------地址计数器的当前值
PROC,ENDP -------------------- 过程定义语句
NAME,TITLE,END -------------------- 程序开始结束语句
MACRO,ENDM --------------------宏定义指令
XLAT (TRANSLATE) --------------- 换码指令
OFFSET -------------------- 返回偏移地址

6.请指出常用的寻址方式有哪些?
答:常用的寻址方式有
立即数寻址
mov ax 1234

寄存器寻址
mov bx,ax

存储器寻址分为如下:
直接寻址
mov ax,[2000h] 默认ds段
mov ax,es:[2000h]

寄存器相对寻址
mov ax,[di+06]

段地址对应的bx/si/di 寄存器默认为DS,对应BP寄存器的默认是SS

寄存器间接寻址
mov ax,[si]

基址变址寻址
mov ax,[bx,si]

相对基址变址寻址
mov ax,[bx+si+06h]

7、说说你理解的栈是什么?
答:一种先进后出的数据结构,一种存储数据的载体形式,附加了操作数据的行为方法,其中栈顶是唯一出口。比如栈内存,栈寄存器。一般局部变量, 函数参数, 返回地址都放在栈中。

8.函数在汇编中是什么样的?
答:函数在汇编中声明如下
函数名 proto :参数类型,:参数类型,......

函数的定义如下:
函数名 proc 参数名:类型,参数名:类型,......
ret
函数名 endp

或者
invoke 函数名,参数,addr 参数

或者不用伪指令
直接
push 参数
push 参数
call 函数名

3.填空选择题

  1. 指令指针寄存器是 eip

10.在串操作指令前使用重复前缀指令REPE,终止串的重复操作条件是 cx为零或zf为零

11.请列举出通用寄存器有哪些? 栈寄存器有哪些?
答:通用寄存器有数据寄存器,变址寄存器,栈寄存器;栈寄存器有ebp,esp。

12.下列属于合法的指令是( D )
A.MOV DS,ES //给段寄存器赋值一定要用通用寄存器
B.MOV [ESI],[EDI] //两个操作数中,必须有一个是寄存器
C.MOV EAX,BL //长度不对
D.MOV [EDI],EBX

13.在下列指令中,D 指令的执行会影响条件码中的CF 位。
A.JMP NEXT
B.JC NEXT
C. INC BX
D.SHL AX,1

  1. 在VS DEBUG 模式下反编译的程序中EBP 中存放的是 十六进制数据

15.在字符串操作指令中,DS : ESI 指向源串,ES : DSI 指向目的串。

  1. CPU 要访问的某一存储单元的实际地址称 物理地址

  2. 循环控制指令LOOPNZ/LOOPNE 控制循环继续执行的条件是 CX=0 且ZF=0

  3. REPZ CMPSW指令,重复执行的终止条件是 cx为零或zf为零

19.用2 种方法将eax 中的值扩大4 倍,请写出汇编指令
(1) SHL EAX,2
(2) IMUL EAX,4

20.与MOV BX,OFFSET VAR指令完全等效的指令是 lea bx,var

======================
1.溢出标志和进位标志有什么区别?
答:溢出标志是OF,表示有符号数运算结果是否超出范围,运算结果已经不正确。进位标志是CF,表示无符号数运算结果是否超出范围,运算结果仍然正确。

2.数据传输指令有哪些,请至少列举5 个。
答:数据传输指令有mov, push,pushf , pusha, pop ,lea ,movs ,xchg ,movsx,movzx等

3.push 和pushf指令有什么区别?
答:push和pushf指令可将源操作数压入栈中,push是普通将字压栈,pushf是标志入栈指令。

4.inc 指令会影响哪些标志位?
答:inc指令会影响的标志位有SF ZF PF AF OF

5.imul 指令和mul 指令有什么区别?
答:imul指令用于有符号数的乘法,操作数的个数为1-3个;而mul是无符号数的乘法指令,操作个数1-2。

6.cmps 指令会影响哪些标志位?
答:AF、CF、OF、SF、PF、ZF。

7.自学一条新指令(使用指导资料的指令介绍格式)
答:XADD 交换并相加指令
交换第一个操作数(目标操作数)与第二个操作数(源操作数),然后将这两个值的和加载到目标操作数。目标操作数可以是寄存器或内存位置;源操作数是寄存器。
CF、PF、AF、SF、ZF 及 OF 标志根据存储到目标操作数的加法结果设置。

8.使用mov 指令实现交换存放在寄存器(交换eax 和ebx 中的数) 中数:
答:
push eax
mov eax,ebx
mov ebx,[esp]

9.使用xchg 指令实现交换edx 和esp中的数据:
答:xchg edx,[esp]

10.已知eax=1,ecx=2,运行lea eax,dword ptr [ecx] 指令后eax=2 ecx=2

11.在32 位汇编中,已知esp=2000,执行pop eax 后esp=2004 再执行push 指令后esp= 2000

12.执行PUSHA指令后会执行哪些操作?执行POPA指令后会执行哪些操作?
压入8 个通寄存器,顺序为:EAXECXEDXEBXESPEBPESEDPOPA 和以上:相反,EDI 开始到EAX 结束

13.已知cf 标志位为0,eax = 0fffffffh 执行inc ax 指令,eax= 10000000, cf=0

14.执行指令imul ebx,dword ptr[1000],10,偏移地址1000 处的数据为5,则ebx=50

15.假设eax=100,符号位SF=0,执行指令cmp eax,200,后eax= 100 ,sf=1

16.已知eax =0xffffffff ,cf=0,执行not eax 后eax=0 ,cf=0

17.在VS 反汇编代码进入函数后会有下面一段代码,那么下面这段代码有具体在做什么呢?
lea edi,[ebp-0E4h]
mov ecx,39h
mov eax,0CCCCCccch
rep stos dword ptr es:[edi]

把栈空间初始化为CC

18.C 语言的函数声明为voidTest (),函数test 内部最后一句反汇编代码和调用处如下:
int Test()
{
0032145B ret
............

}

003214D5 call Test (0321050h)

003214DA mov dword ptr [ret],eax

则执行ret 前eip=0032145B ,执行ret 后eip= 003214DA

19.已知一个整形变量n=0, 以下
int n = 0;
_asm mov eax,0x0000ffff
_asm mov ebx,0xffff0000
_asm or eax,ebx
_asm mov n,eax
printf("%d",n);
指令在VS 内嵌汇编中执行,然后print("%d",n)将输出 -1

========================

1.OPCode 和汇编语言有什么关系?
答:OPCode与汇编指令并非是单纯的对应关系,同一opcode对应的汇编指令不一定相同,反之也一样。

  1. OPCode 就是机器码吗?
    答:不一定就是,例如PHP虚拟机(Zend VM)、java虚拟机(JVM)以及一些软件保护虚拟机中的最小操作单元都可以称之为OPCode。在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的指令规范指定。

  2. 所有不同架构的CPU 都有自己的OPCode 吗?
    答:可能是自己的也可能和其他一样。

3.填空题

  1. OPCode 为0xCC 汇编语言代码为 int 3 ,OPCode 为0X50 汇编语言代码为 push eax
  1. 80X86 汇编指令最少由 1 个字节构成,最多由 16 个字节构成.

6.请写出OPCode 的格式:
前缀prefixes+代码code+构造模式modR/M(mod+reg+r/m)+SIB+位移+立即数

7.请列举所有OPCode 的前缀:
66 -- 切换操作数大小
67 -- 切换地址大小
F2/F3 -- 重复操作前缀
2E/36/3E/26/64/65 -- 修改默认段
F0 -- 锁定前缀

  1. 切换操作数大小”切换"的意思是将其在两种状态间来回切换,而并非特指某种状态,那么OPCode 为40 的反汇编代码为inc eax,那么加上前缀66 即OPCode 6640 的指令为 inc ax
    关于无效的前缀,那么OPCode 为8AC1的反编代码为MOV AL,CL,那么加上前缀66 即OPCode 66 8AC1的指令为 mov al cl

  2. 创建操作数类型描述,常见操作数大小描述,请说明:
    常见操作数类型编码和大小描述
    a 两个单字内存操作数或两个双字内存操作数,依据操作数尺寸属性决定(仅在 BOUND 指
    令中使用)
    b 字节,不论操作数尺寸属性
    c 字节或字,依据操作数尺寸属性决定
    d 双字,不论操作数尺寸属性
    dq 八字(Double-quadword),不论操作数尺寸属性
    p 32 位,48 位或者 80 位指针,依据操作数尺寸属性决定
    pd 128 位紧缩双精度浮点数
    pi 四字 MMX 寄存器(如 mm0)
    ps 128 位紧缩单精度浮点数
    q 四字操作数,不论操作数尺寸属性
    s 6 字节或 10 字节伪描述符(pseudo-descriptor)
    ss 128 位紧缩单精度浮点数的标量部分(scalar element of a 128-bit packed single-precision
    floating data)
    si 双字整数寄存器(如 eax)
    v 字,双字或四字(64 位模式),依据操作数尺寸决定
    w 字,不论操作数尺寸
    z 在 16 位模式中为字,在 32 位或 64 位环境中为双字

10.ModR/M 中的R/M 域为[--][--]时,表示什么意思:
SIB字节

11.ModR/M 部分由哪几部分组成
比例scale 索引 index 基数base

12.根据ModR/M 信息确认是否有SIB字节可以查Intel 手册,当Mod !=11b,并且.R/M 的
值为 100b 的时候,表示指令后续有SIB 字节,并且该内存操作对象由SIB 编码。

4.扩展题
请在intel 手册中查找OPCode:
F0:26:C7 8491AA00000011000000 的汇编代码是
F0 :lock
26 :ES
C7 : mov Ev,Iz E:到MODR/M左边找 32位,I:立即数 32位
84 : [--][--]+32disp
91 : [edx*4][ecx]

LOCK MOV DWORD PTR ES: [EDX*4 + ECX + 0AA], 11

推荐阅读更多精彩内容

  • 每个时代,都不会亏待会学习的人。 大家好,我是 yes。 对于我们程序员来说计算机的重要性不言而喻,相信大家对计算...
    yes的练级攻略阅读 942评论 5 15
  • 前言 话说Java中String是有长度限制的,听到这里很多人不禁要问,String还有长度限制?是的有,而且在J...
    程序员追风阅读 258评论 0 4
  • 寻址方式(或编址方式)指的是确定本条指令的数据地址及下一条要执行的指令地址的方法。 (1)立即数寻址 所需的操作数...
    Wovw阅读 49评论 0 2
  • 在我及我旁边的朋友面试经历来看,这个问题几乎没有问到过,这两天看到公众号【JAVA葵花宝典】里的一篇文章的谈到了这...
    重楼_yin阅读 247评论 0 2
  • • 查看CPU信息:lscpu • 查看内存信息:free -h • 查看硬盘信息:df -h 显示当前文件夹的大...
    呆呱呱阅读 575评论 0 16