U3
211275022田昊东¶
6.¶
变量 | 地址 |
---|---|
xptr | R[ebp]+8 |
yptr | R[ebp]+12 |
zptr | R[ebp]+16 |
void func(int*xptr,int*yptr,int*zptr)
{
int x=*xptr,y=*yptr,z=*zptr;
*yptr=x;
*zptr=y;
*xptr=z;
}
8.¶
变化 | 内容 | OF | SF | ZF | CF |
---|---|---|---|---|---|
%edx | 0x0000 0070 | 0 | 0 | 0 | 1 |
%ecx | 0x8000 0008 | 1 | 1 | 0 | 1 |
%bx | 0xff00 | \ | 1 | 0 | \ |
\ | \ | 0 | 1 | 0 | 0 |
%ecx | 0x11e2 5500 | 1 | \ | \ | 1 |
%dx-%ax | 0x0093 0x0000 | 1 | \ | \ | 1 |
%cx | 0x000f | 0 | 0 | 0 | 0 |
9.¶
-
注释:
-
c movl 12(%ebp),%ecx//%ecx<-R[R[ebp]+12]用%ecx存储y的值 sall $8,%ecx//将%ecx中的值左移8位存储在%ecx中 movl 8(%ebp),%eax//%eax<-R[R[ebp]+8]用%eax存储x的值 movl 20(%ebp),%edx//%edx<-R[R[ebp]+20]用%edx存储k值 imull %edx,%eax//计算x*k并存入%eax movl 16(%ebp),%edx//%edx<-R[R[ebp]+16]用%edx存储z的值 andl $65520,%edx//计算z&0xFFF0存入%edx addl %ecx,%edx//计算z&FFF0+y*256并存入%edx subl %edx,%eax//计算x*k-(z&FFF0+y*256)并存入%eax(作为返回值)
-
缺失部分
x*k-(z&FFF0+y*256)
11.¶
- (1)
- 目标地址由三部分组成:
0x8043838c+2(je指令长度)+0x08(偏移量)=0x804386
- 同理call的目标地址也由三部分组成,由于使用小端存储,可以从指令得出偏移量
0000001e
,故目标地址为0x80438e+5+0x0000001e=80483b1
- (4)
- 同理转移地址由三部分组成
0x8048296+5+0xffffff00==0x804819b
14.¶
-
(1)
-
assembly movw 8(%ebp) , %bx//将变量x移入%bx movw 12(%ebp), %si//将变量y移入%si movw 16(%ebp), %cx//将变量k移入%cx .L1: movw %si, %dx//将y移入%dx movw %dx, %ax//将y又移入%ax sarw $15, %dx//将y右移15位后存入%dx idiv %cx//要用dx-ax中的值除以%cx //dx-ax就是进行32位符号扩展后的y //相当于将y/k的商(y/k)存入ax,余数(y%k)存入dx imulw %dx, %bx//将y%k*x的值存入存入%bx decw %cx//将k-1存入%cx testw %cx, %cx//将%cx内容做与并设置符号位,不改变寄存器内容 jle .L2//如果与操作结果为0(k=0)则跳转到L2,跳出循环 cmpw %cx, %si//计算y-k设置符号位,但不改变寄存器的内容 jg .L1//如果y>k则跳转到L1继续循环 .L2: movswl %bx, %eax//把%bx中内容做符号位扩展之后存入%eax(作为返回值返回)
-
(2)
- 被调用者保存寄存器:%bx、%si
- 调用者保存寄存器:%ax、%cx、%dx
- 被调用者寄存器%ebx、%esi需要被保存
- (3)
- 因为执行除法之前需要先对被除数进行扩展,而该除法为有符号除法,因此使用sar算数右移,从而使得dx-ax为数字的符号位扩展
16.¶
-
先对程序头部对x的处理分析:
-
计算x+3
-
比较x+3与7的大小关系,如果x+3>7则跳转到L7;否则跳转到.L8+4*(x+3)
-
对应关系为
标号 x 1 L7 -3 2 L2 -2 3 L2 -1 4 L3 0 5 L4 1 6 L5 2 7 L7 3 8 L6 4 -
由于L7是default分支,可知有如下情况会进行跳转:
- x>10
- x=-3;x=3
- 除default部份外:有以下标号会执行同一case分支
- x=-1,x=-2都会跳转到L2
17.¶
c int test(char a,unsigned short b,unsigned short c,short *p) { *p=a; return b*c; }
18.¶
-
(1)(2)
-
行数 EBP(1) ESP(2) 3 0xbc00 001c 0xbc00 001c 10 0xbc00 001c 0xbbff fff4 13 0xbc00 0030 0xbc00 0020 -
(3)
-
x:
0xbc00 0018
-
y:
0xbc00 0014
-
(4)
-
地址 内容 解释 0xbc00 001c 0xbc00 0030 <-%ebp 0xbc00 0018 <-x 0xbc00 0014 <-y 0xbc00 0010 0xbc00 000c 0xbc00 0008 0xbc00 0004 0xbc00 0000 0xbbff fffc 0xbc00 0014 0xbbff fff8 0xbc00 0018 0xbbff fff4 0x0804 c000 字符串地址 0xbbff fff0 执行scanf后的返回地址 <-%esp
23.¶
- 结合汇编的执行过程可知,目标元素的地址是
a+4(k+9j+63i)
,即a+4*9*7i+4*9j+4k
且数组总大小为4536字节 - 因此推测a[i]中有63个元素,252字节,因此L=4536/252=18;
- a[i][j]中有9个元素,因此M=64/9=7;
- 故a[i][j][k]有N=9;
26.¶
-
表达式 type 汇编 uptr->s1.y short movw 4(%eax), %ax movw %ax, (%edx) &uptr->a1.z short* leal 6(%eax), %eax movl %eax, (%edx) uptr->s2.a short* movl %eax, (%edx) uptr->s2.a[uptr->s2.b] short movl 4(%eax), %ecx movl (%eax, %ecx, 2) movl %eax, (%edx) *uptr->s2.p char movl 8(%eax), %eax movb (%eax), %al movb %al, (%edx)
27.¶
- (1)
- s:0;c:2;i:4;d:8;
- 总大小:12
- 起始位置:4的整数倍
- (2)
- i:0;s:4;c:6;d:7;
- 总大小:8
- 起始位置:4
- (3)
- c:0;s:2;i:4;d:8;
- 总大小:12
- 起始位置:4
- (4)
- s:0;c:6;
- 总大小:8
- 起始位置:2
- (5)
- c:0;s:4;i:8;d:12;e:16;
- 总大小:24
- 起始位置:4
- (6)
- c:0;s:36;d:40;
- 总大小:44
- 起始位置:4
30.¶
-
由x86入口参数表知三个参数分别存储在rdi、rsi、rdx中
-
由汇编代码可知:
- b存储在%rdx;c存储在%edi;a存储在%rsi。因此三个参数的顺序为cab
- 由于在4中进行了符号位扩展,因此可知*b为32为有符号整数,*a为64位整数,而c为32位整数或64位整数
- 由此推测函数原型:
- abc(long long c, long long*a, int*b)
- abc(int c, long long*a, int*b)
- abc(long long c, unsigned long long*a, int*b)
- abc(int c, unsigned int*a, int*b)
32.¶
- 对汇编代码进行分析:
- 首先装载参数:
%eax<-i
、%ecx<-sptr
- 然后进行简单计算(计算后续需要访问的复杂数据类型的地址)
%ebx=28i
%edx=7i
- 进一步得到:
%edx=M[sptr+4+28i](xptr->idx)+7i
%eax(val)=M[sptr](l_data)+M[sptr+0xc8](r_data)
M[sptr+4+28i+4+4*(xptr->idx)](xptr->a[xptr->idx])=%eax(val)
- 可以得x[LEN]占用空间0xc8-4=196字节
- 由于M[sptr+4+28i]可知line_struct的大小为28字节
- 故LEN=196/28=7
-
由
M[sptr+4+28i](xptr->idx)
可知idx应该在a的前面 -
LEN=7
-
line_struct:
-
c line_struct{ int idx; unsigned a[6]; };