Skip to content

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]; };