简介:本文是博主汇编测试的试题及答案分析,属个人理解,如有错误,欢迎指教
1:执行指令ADD %eax,%edx,其中%eax为0x0a517c44,%edx为0x0839317c,%edx结果为______(以十六进制小写格式表示例0xffffffff)。
正确答案:0x128aadc0
2:执行以下指令,最终%eax的结果为______(以十六进制格式小写表示例0xffffffff)。
movl $0xcc514c7d,%edx #1100(c)负数
movl $0x60fd5750,%eax #0110(6)正数
cmpl %eax,%edx #edx-eax<0
jge .L2 #有符号数
subl %edx,%eax #执行eax-edx,FFFF FFFF 94AC 0AD3,取后面8位
jmp .L3
.L2:
subl %eax,%edx
movl %edx,%eax
.L3:
正确答案:0x94ac0ad3
3:假设寄存器%dh的值为0x0e,%eax的值为0xf923af9f,执行以下指令
movsbl %dh,%eax
%eax的值为______(以十六进制小写字符格式表示例0xffffffff该题请补齐八位)。
解析: 取dh做符号位扩展成8位,注意符号位为0而不是1
正确答案:0x0000000e
[有更改]4: 假设寄存器 %ebx的值为0x82b2544d,执行以下指令后
movl %ebx,%ecx
movw $0x5db2,%bx //ebx变为0x82b25db2
movb $0xeb,%bl//ebx变为0x82b25deb
cmpl %ecx,%ebx
jae .L1 //按无符号数解释,ebx>ecx,跳转到.L1
addl $0x1,%ebx
jmp .L2
.L1:
subl $0x1,%ebx
.L2:
%ebx的值为______(以十六进制格式小写表示例0xffffffff)。
*解析:
注意注意!
cmp操作不是用前面的操作数减后面的,而是用后面的操作数减前面的,我之前没有发现这个错误,反而认为是mov指令的问题,在此改正(图来自http://c.biancheng.net/view/3529.html),也就是说64位字长的模式下并且把32位的操作数放进64位的寄存器,或者把较多位的操作数放进较少位的存储器,才会把存储器清0,由于这里是32位操作数以及32位的寄存器,所以把16位或者8位的操作数放进32位的寄存器前面的数是不变的。
正确答案:0x82b25dea
5:已知寄存器及其现有值如下: EAX=0x7e79b2a1, EDX=0x578a7528。指令movsbl %dh, %eax执行完后,EAX=_______?(如果无法通过编译,答案填 “错误,编译不能通过” 否则答案格式形如0xffffffff).
解析: dx的高8位,即0x75做符号位扩展
正确答案:0x00000075
6:已知寄存器%eax中的值为0xbf18b9bd,%ebx中的值为0x42a32591,%ecx的值为0xa2cc0d55,%edx的值为0xd532e5ea。 求下列操作数的值(十进制): 0x2d(,%eax,6)
解析:
溢出了整数的表示范围,取舍弃二进制的前4位得到 0111 1010 1001 0100 0101 1010 1001 1011,转化为十进制
正确答案:2056542875
7:某程序中有整形变量a=0x63361162, b=0x2d341981, c=0xc5784bf1, d=0xcda3fd5d 程序代码中有如下语句:
b=&a; 修改b的值为a(可理解为b引用了a的值)
d=&c;修改d的值为c
a=a+0x53de2812;修改a的值(设为a1)
*d=*b; 修改d指向的c的值为b指向的值a1
则此时语句 printf(“c=%d\n”, c); 给出结果为:(十进制)
解析: 把a的值修改了,由于b引用了a,所以b的值就是更改后a的值,
这里的整型变量a是有符号数,a肯定是一个负数,给出的01序列是补码,其相应的原码为0100 1000 1110 1011 1100 0110 1000 1100,即1223411340,最后加上负号得到-1223411340。
正确答案:-1223411340
8:根据操作数特点,用恰当的MOV类指令补全下列残缺数据传送指令:
_______ %eax,%ebx
_______ %eax,%bx
_______ %eax,%ecx(格式形如:movl)
正确答案:movl,movw,movl
9:已知 %eax=0X100,%ebx=0X3; 内存中指定地址的值列表如下:
地址 值
0X100 0X44
0X104 0XFF
0X108 0XB2
0X10C 0X32
则指令 addl 0X88,(%eax,%ebx,4)将地址__________中的值更新为___________。 (格式为16进制大写。)
正确答案:0X10C,0XBA
10:%ah中存有某变量值0x34。则指令 SHL $5, %ah 执行后 %ah = _____。(答案格式形如0x00)
正确答案:0x80
11:1.在下面的反汇编二进制代码中,有些信息缺失并以X代替。 请回答下列关于指令的问题。下面je指令的目标是什么?(答案请以十六进制小写形式给出,例如:8048248f)
595b73e2: 74 46 je XXXXXXXX
595b73e4: e8 1e 00 00 00 call 80482b4
请问:XXXXXXXX = ?
解析:
根据书上的解释可知595b73e2: 74 46 je XXXXXXXX 中74表示操作码,46就是跳转地址与je指令下一条指令的差,所以只需要用je指令的下一条指令的地址595b73e4+46即可得到跳转的地址
正确答案:595b742a
12:3.mov指令的地址是多少?(答案请以十六进制小写形式给出,例如:8048248f)
XXXXXXXX: 74 13 je af875e38
XXXXXXXX: b8 00 00 00 00 mov $0x0, %eax
请问:第一行XXXXXXXX = ?
第二行XXXXXXXX = ?
解析: 由前一题思路可知第一行地址为af875e38 -13-2,第二行的地址为第一行的地址+2
正确答案:af875e23,af875e25
13:在下面的代码中,跳转目标的编码是PC有关的,且是一个4字节的补码数。 字节按照从最低位到最高位的顺序列出,反映出IA32的小端法字节顺序。跳转目标的地址是什么?(答案请以十六进制小写形式给出,例如:8048248f)
105d7e90: e9 f1ffffff jmp XXXXXXXX
105d7e95: 90 nop
解析:由于是小端法,由上一题的思路,知跳转地址应该是FFFF FFF1+105d7e95的值,FFFF FFF1是-15的补码,所以跳转地址为105d7e95-15=105d7e86
正确答案:105d7e86
14:给定C函数如下:
int proc(void)
{
int x, y;
scanf(“%x %x”, &y, &x);
return x-y;
}
GCC 产生以下代码:
1 proc:
2 pushl %ebp
3 movl %esp, %ebp
4 subl $46, %esp
5 leal -4(%ebp), %eax
6 movl %eax, 8(%esp)
7 leal -8(%ebp), %eax
8 movl %eax, 4(%esp)
9 movl $.LCO, (%esp) //Pointer to string “x% x%”
10 call scanf //Diagram stack frame at this point
11 movl -4(%ebp), %eax
12 subl -8(%ebp), %eax
13 leave
14 ret
假设过程proc开始执行时寄存器 %esp的值为0x6a03a621, 寄存器 %ebp的值为0x09f91cde。 如果proc调用scanf(第10行),而scanf从标准输入中读入值 0x75 和 0x4,假设字符串 “%x %x”存放在存储器位置 0xa72aee3a。请问,(答案请以十六进制小写形式给出,形如:0x8877991a)
A. 第3行 %ebp 的值被设置成了多少?
B. 第4行 %esp 的值被设置成了多少?
C. 局部变量 x 和 y 的存放地址是什么?
D. 指出proc未使用的栈帧区域。(例如0x1234568~0x1234567)
解析:
开始esp要退4个字节给ebp压栈,所以esp的值已经变为了
0x6a03a621-0x4=0x6a03a61d,
所以ebp的值被设置成0x6a03a61d
第四行esp的值被设置成
0x6a03a61d-0x2e(46)=0x6a03a5ef。
局部变量x存放的地址为
ebp-4=0x6a03a61d-4=0x6a03a619
y存放的地址为
ebp-8=0x6a03a61d-0x8=0x6a03a615
由栈帧结构可知,未使用的栈帧区域为0x6a03a611~0x6a03a5fb
正确答案:0x6a03a61d,0x6a03a5ef,0x6a03a619,0x6a03a615,0x6a03a611~0x6a03a5fb
总结:最近一段时间有些堵得慌,已经有差不多1个多月没碰过博客了,每次遇到不会的题目就是进行如下循环
心如死灰—>死灰复燃—>心如死灰。
这次的测试发挥的也不是很好,汇编仍然是一个很大的漏洞,稍不注意细节就会出错,还是要多做自我检讨和自我反省。