假設某個C語言函數func的原型聲明如下:
void func(int *xptr, int *yptr, int *zptr);
函數func的過程體對應的機器級代碼用AT&T匯編形式表示如下:
movl 8(%ebp), %eax
movl 12(%ebp), %ebx
movl 16(%ebp), %ecx
movl (%ebx), %edx
movl (%ecx), %esi
movl (%eax), %edi
movl %edi, (%ebx)
movl %edx, (%ecx)
movl %esi, (%eax)
請回答下列問題或完成下列任務:
(1)在過程體開始時三個入口參數對應實參所存放的存儲單元地址是什么?(提示:當前棧幀底部由幀指針寄存器EBP指示,棧從高地址向低地址生長,參數入棧順序為從右到左,因此總是最右邊參數的地址最大)
(2)根據上述機器級代碼寫出函數func的C語言代碼
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
(1)xptr、yptr、zptr對應實參所存放的存儲單元地址分別為:R[ebp]+8、R[ebp]+12、R[ebp]+16。
(2)函數func的C語言代碼如下:
void func(int *xptr, int *yptr, int *zptr)
{
int tempx = *xptr;
int tempy = *yptr;
int tempz = *zptr;
*yptr = tempx;
*zptr = tempy;
*xptr = tempz;
}
題目解析:
(1)xptr、yptr、zptr對應實參所存放的存儲單元地址分別為:R[ebp]+8、R[ebp]+12、R[ebp]+16。
(2)函數func的C語言代碼如下:
void func(int *xptr, int *yptr, int *zptr)
{
int tempx = *xptr;
int tempy = *yptr;
int tempz = *zptr;
*yptr = tempx;
*zptr = tempy;
*xptr = tempz;
}
2
假設函數operate的部分C代碼如下:
1 int operate(int x, int y, int z, int k)
2 {
3 int v = ___________________;
4 return v;
5 }
以下匯編用來實現第3行語句的功能,請寫出每條匯編指令的注釋,並根據以下匯編代碼,填寫operate函數缺失的部分。
1 movl 12(%ebp), %ecx
2 sall 8, %ecx
3 movl 8(%ebp), %eax
4 movl 20(%ebp), %edx
5 imull %edx, %eax
6 movl 16(%ebp), %edx
7 andl 65520, %edx
8 addl %ecx, %edx
9 subl %edx, %eax
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
int v = xk - (z&0xFFF0 + y256);
或
int v = x*k - (z&65520 + (y<<8));
或其他功能一樣但表達稍有不同的語句。
1 movl 12(%ebp), %ecx //R[ecx]<-M[R[ebp]+12],將y送ECX
2 sall 8, %ecx //R[ecx]<-R[ecx]<<8,y*256送ECX
3 movl 8(%ebp), %eax //R[eax]<-M[R[ebp]+8],將x送EAX
4 movl 20(%ebp), %edx //R[edx]<-M[R[ebp]+20],將k送EDX
5 imull %edx, %eax //R[eax]<-R[eax]R[edx],將xk送EAX
6 movl 16(%ebp), %edx //R[edx]<-M[R[ebp]+16],將z送EDX
7 andl 65520, %edx //R[edx]<-R[edx]&65520,將z&65520送EDX
8 addl %ecx, %edx //R[edx]<-R[edx]+R[ecx],將z&65520+y*256送EDX
9 subl %edx, %eax //R[eax]<-R[eax]-R[edx],將xk-(z&65520+y256)送EAX
題目解析:
int v = xk - (z&0xFFF0 + y256);或int v = x*k - (z&65520 + (y<<8));或其他功能一樣但表達稍有不同的語句。
1 movl 12(%ebp), %ecx //R[ecx]<-M[R[ebp]+12],將y送ECX
2 sall 8, %ecx //R[ecx]<-R[ecx]<<8,y*256送ECX
3 movl 8(%ebp), %eax //R[eax]<-M[R[ebp]+8],將x送EAX
4 movl 20(%ebp), %edx //R[edx]<-M[R[ebp]+20],將k送EDX
5 imull %edx, %eax //R[eax]<-R[eax]R[edx],將xk送EAX
6 movl 16(%ebp), %edx //R[edx]<-M[R[ebp]+16],將z送EDX
7 andl 65520, %edx //R[edx]<-R[edx]&65520,將z&65520送EDX
8 addl %ecx, %edx //R[edx]<-R[edx]+R[ecx],將z&65520+y*256送EDX
9 subl %edx, %eax //R[eax]<-R[eax]-R[edx],將xk-(z&65520+y256)送EAX
3
已知函數test的入口參數有a、b、c和p,C語言過程體代碼如下:
*p = a;
return b*c;
函數test過程體對應的匯編代碼如下:
1 movl 20(%ebp), %edx
2 movsbw 8(%ebp), %ax
3 movw %ax, (%edx)
4 movzwl 12(%ebp), %eax
5 movzwl 16(%ebp), %ecx
6 mull %ecx, %eax
寫出函數test的原型,給出返回參數的類型以及入口參數a、b、c和p的類型和順序。
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
unsigned int test(char a, unsigned short b, unsigned short c, shrot *p);
1)第3條指令對應的是*p=a,結合第2條可知a為第1個參數(4個參數偏移分別為20、8、12、16,最左邊的參數偏移最小)且為char型(movsbw,將字節符號擴展到16位);
2)由第1、3條指令可知p為第4個參數,其類型為short *;
3)由第4和第6條指令(R[eax]<-R[eax]*R[ecx],eax在前對應b,ecx在后對應c)可知b為第2個參數,其類型為unsigned short(movzwl,16位零擴展到32位);
4)由第5和第6條指令可知c為第3個參數(偏移值16),其類型為unsigned short(原因同b)
5)第6條指令為2個無符號32位數相乘,其結果為32位無符號數,因此函數返回值為unsigned int
題目解析:
unsigned int test(char a, unsigned short b, unsigned short c, shrot *p);
1)第3條指令對應的是*p=a,結合第2條可知a為第1個參數(4個參數偏移分別為20、8、12、16,最左邊的參數偏移最小)且為char型(movsbw,將字節符號擴展到16位);
2)由第1、3條指令可知p為第4個參數,其類型為short *;
3)由第4和第6條指令(R[eax]<-R[eax]*R[ecx],eax在前對應b,ecx在后對應c)可知b為第2個參數,其類型為unsigned short(movzwl,16位零擴展到32位);
4)由第5和第6條指令可知c為第3個參數(偏移值16),其類型為unsigned short(原因同b)
5)第6條指令為2個無符號32位數相乘,其結果為32位無符號數,因此函數返回值為unsigned int
4
已知函數func的C語言代碼框架及其過程體對應的匯編代碼如下所示,根據對應的匯編代碼填寫C代碼中缺失的表達式。(jg的轉移條件為SF=OF且ZF=0,帶符號數A>B;jle的轉移條件為SF!=OF或ZF=1,帶符號數A<=B;jl的轉移條件為SF!=OF且ZF=0,帶符號數A<B)
int func (int x, int y)
{
int z = __________________;
if (_____________) {
if (_____________)
z = _______________;
else
z = _______________;
} else if (_____________)
z = _____________;
return z;
}
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
int func(int x, int y)
{
int z = x*y;
if (x <= -100) {
if (y > x)
z = x + y;
else
z = x - y;
} else if ( x >= 16)
z = x&y;
return z;
}
題目解析:
int func(int x, int y)
{
int z = x*y;
if (x <= -100) {
if (y > x)
z = x + y;
else
z = x - y;
} else if ( x >= 16)
z = x&y;
return z;}
5
已知函數f1的C語言代碼框架及其過程體對應的匯編代碼如下所示,根據對應的匯編代碼填寫C代碼中缺失的部分,並說明函數f1的功能。(test根據兩個操作數相“與”的結果來設置標志位,但不改變原操作數;je的跳轉條件為ZF=1,即等於0;jne的跳轉條件是ZF=0,即不等於0)
int f1(unsigned x)
{
int y = 0;
while(__________) {
________;
________;
}
return ________;
}
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
int f1(unsigned x)
{
int y = 0;
while(x != 0) {
y ^= x;
x >>= 1;
}
return y&0x1;
}
f1的功能是返回(x(x>>1)(x>>2)^...)&0x1,因此f1用於檢測x的奇偶性,有奇數個1則返回1,否則返回0。
題目解析:
int f1(unsigned x)
{
int y = 0;
while(x != 0)
{
y ^= x;
x >>= 1;
}
return y&0x1;
}
f1的功能是返回(x(x>>1)(x>>2)^...)&0x1,因此f1用於檢測x的奇偶性,有奇數個1則返回1,否則返回0。
6
已知函數sw的C語言代碼框架如下:
int sw(int x){
int v = 0;
switch(x)
{//switch語句中的處理部分省略
}
return v;}
對函數sw進行編譯,得到函數過程體中開始部分的匯編代碼以及跳轉表如下(ja的跳轉條件是CF=0且ZF=0,即無符號整數A>B):
試回答進入.L2-.L7時x的取值。
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
由前4句代碼可知x+3>7時進入L7分支,否則根據跳轉表進行跳轉,根據跳轉表,x與跳轉目標標號的關系為:
x+3=0: .L7
x+3=1: .L2
x+3=2: .L2
x+3=3: .L3
x+3=4: .L4
x+3=5: .L5
x+3=6: .L7
x+3=7: .L6
綜上,x與跳轉分支的關系為:
case -2:
case -1:
//跳轉.L2
break;
case 0:
//跳轉.L3
break;
case 1:
//跳轉.L4
break;
case 2:
//跳轉.L5
break;
case 4:
//跳轉.L6
break;
default:
//跳轉.L7
break;
題目解析:
由前4句代碼可知x+3>7時進入L7分支,否則根據跳轉表進行跳轉,根據跳轉表,x與跳轉目標標號的關系為:
x+3=0: .L7
x+3=1: .L2
x+3=2: .L2
x+3=3: .L3
x+3=4: .L4
x+3=5: .L5
x+3=6: .L7
x+3=7: .L6
綜上,x與跳轉分支的關系為:
case -2:
case -1:
//跳轉.L2
break;
case 0:
//跳轉.L3
break;
case 1:
//跳轉.L4
break;
case 2:
//跳轉.L5
break;
case 4:
//跳轉.L6
break;
default:
//跳轉.L7
break;
7
已知函數funct的C語言代碼如下:
include <stdio.h>
int funct(void)
{
int x, y;
scanf("%d,%d", &x, &y);
return x-y;
}
函數funct對應的匯編代碼如下:
假設函數funct開始執行時,R[esp]=0xbc000020, R[ebp] = 0xbc000030, 指向字符串“%d %d”的指針為0x804c0000。試回答下列問題:
1)執行第3、10、13行的指令后,寄存器EBP中的內容分別是什么?
2)執行第3、10、13行的指令后,寄存器ESP中的內容分別是什么?
3)局部變量x和y所在存儲單元的地址分別是什么?
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
每次執行pushl指令后,R[esp]=R[esp]-4;
第2行執行完后,R[esp]=0xbc00001c;
執行第3條指令后,R[ebp]=R[esp]=0xbc00001c;
執行第4條指令后,R[esp]=0xbbfffff4;
第5-9條指令不改變ESP和EBP
第10條指令執行scanf函數前,返回地址入棧,ESP變為0xbbfffff0,scanf執行完畢后,返回地址出棧,ESP變為0xbbfffff4;
第11-12條指令不改變ESP和EBP
執行第13條指令后,EBP和ESP的內容恢復為剛進入funct時的值0xbc000030和0xbc000020。
因此:
1)執行第3、10、13行的指令后,寄存器EBP中的內容分別是0xbc00001c、0xbc00001c、0xbc000030
2)執行第3、10、13行的指令后,寄存器ESP中的內容分別是0xbc00001c、0xbbfffff4、0xbc000020
3)由指令5-8可知x和y的地址分別為R[ebp]-4=0xbc000018、R[ebp]-8=0xbc000014
題目解析:
每次執行pushl指令后,R[esp]=R[esp]-4;
第2行執行完后,R[esp]=0xbc00001c;
執行第3條指令后,R[ebp]=R[esp]=0xbc00001c;
執行第4條指令后,R[esp]=0xbbfffff4;
第5-9條指令不改變ESP和EBP第10條指令執行scanf函數前,返回地址入棧,ESP變為0xbbfffff0,scanf執行完畢后,返回地址出棧,ESP變為0xbbfffff4;
第11-12條指令不改變ESP和EBP執行第13條指令后,EBP和ESP的內容恢復為剛進入funct時的值0xbc000030和0xbc000020。
因此:
1)執行第3、10、13行的指令后,寄存器EBP中的內容分別是0xbc00001c、0xbc00001c、0xbc000030
2)執行第3、10、13行的指令后,寄存器ESP中的內容分別是0xbc00001c、0xbbfffff4、0xbc000020
3)由指令5-8可知x和y的地址分別為R[ebp]-4=0xbc000018、R[ebp]-8=0xbc000014
假設函數sumij的C代碼如下,其中M,N是用define聲明的常數
1 int a[M][N], b[N][M];
2
3 int sumij(int i, int j) {
4 return a[i][j] + b[j][i];
5 }
已知函數sumij的過程體對應的匯編代碼如下:
1 movl 8(%ebp), %ecx
2 movl 12(%ebp), %edx
3 leal (,%ecx, 8), %eax
4 subl %ecx, %eax
5 addl %edx, %eax
6 leal (%edx, %edx, 4), %edx
7 addl %ecx, %edx
8 movl a(, %eax, 4), %eax //a為數組a的首地址
9 addl b(,%edx, 4), %eax //b為數組b的首地址
根據上述匯編代碼,確定M和N的值。
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
1 movl 8(%ebp), %ecx //R[ecx] = i
2 movl 12(%ebp), %edx //R[edx] = j
3 leal (,%ecx, 8), %eax //R[eax] = 8*i
4 subl %ecx, %eax //R[eax] = 8i - i = 7i
5 addl %edx, %eax //R[eax] = 7*i + j
6 leal (%edx, %edx, 4), %edx //R[edx] = 4j + j = 5j
7 addl %ecx, %edx //R[edx] = 5*j + i
8 movl a(, %eax, 4), %eax //R[eax] = M[a+74i + 4*j
9 addl b(,%edx, 4), %eax //R[eax] = M[a + 74i +4j] + M[b + 54j + 4i
由此可知,M=5,N=7
題目解析:
1 movl 8(%ebp), %ecx //R[ecx] = i
2 movl 12(%ebp), %edx //R[edx] = j
3 leal (,%ecx, 8), %eax //R[eax] = 8*i
4 subl %ecx, %eax //R[eax] = 8i - i = 7i
5 addl %edx, %eax //R[eax] = 7*i + j
6 leal (%edx, %edx, 4), %edx //R[edx] = 4j + j = 5j
7 addl %ecx, %edx //R[edx] = 5*j + i
8 movl a(, %eax, 4), %eax //R[eax] = M[a+74i + 4*j
9 addl b(,%edx, 4), %eax //R[eax] = M[a + 74i +4j] + M[b + 54j + 4i由此可知,M=5,N=7
2
假設結構體node的定義、函數np_init的C代碼及其對應部分匯編代碼如下:
struct node {
int *p;
struct {
int x; int y;
} s;
struct node *next;
};
void np_init(struct node *np){
np->s.x = ______________;
np->p = _______________;
np->next = ____________;
}
movl 8(%ebp), %eax
movl 8(%eax), %edx
movl %edx, 4(%eax)
leal 4(%eax), %edx
movl %edx, (%eax)
movl %eax, 12(%eax)
回答下列問題:
(1)結構node所需存儲空間有多少字節?成員p、s.x、s.y、和next的偏移地址分別為多少?
(2)根據匯編代碼填寫np_init中缺失的表達式。
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
(1)p和next是地址,各占4字節,x和y各占4字節,總共16字節;成員p、s.x、s.y、和next的偏移地址分別為0、4、8、12。
(2)
movl 8(%ebp), %eax //R[eax] = np
movl 8(%eax), %edx //R[edx] = np->s.y
movl %edx, 4(%eax) //np->s.x = np->s.y
leal 4(%eax), %edx //R[edx] = np + 4
movl %edx, (%eax) //np->p = np + 4 = &(np->s.x)
movl %eax, 12(%eax) //np->nexp = np
因此缺失部分表達式如下:
void np_init(struct node *np){
np->s.x = np->s.y;
np->p = &(np->s.x);
np->next = np;
}
題目解析:
(1)p和next是地址,各占4字節,x和y各占4字節,總共16字節;成員p、s.x、s.y、和next的偏移地址分別為0、4、8、12。
(2)
movl 8(%ebp), %eax //R[eax] = np
movl 8(%eax), %edx //R[edx] = np->s.y
movl %edx, 4(%eax) //np->s.x = np->s.y
leal 4(%eax), %edx //R[edx] = np + 4
movl %edx, (%eax) //np->p = np + 4 = &(np->s.x)
movl %eax, 12(%eax) //np->nexp = np
因此缺失部分表達式如下:
void np_init(struct node *np){
np->s.x = np->s.y;
np->p = &(np->s.x);
np->next = np;
}
3
給出下列各個結構類型中每個成員的偏移量、結構總大小。
(1)struct S1 {short s; char c; int i; char d;};
(2)struct S2 {int i; short s; char c; char d;};
(3)struct S3 {char c; shrot s; int i; char d;};
(4)struct S4 {short s[3]; char c;};
(5)struct S5 {char c[3];short *s; int i; char d; double e;};
(6)struct S6 {struct S1 c[3];struct S2 *s;char d;};
要求:
1)圖片上傳(建議Chrome,可對圖片復制粘貼)
2)圖片方向正確
3)圖片上有簽名
回答:
參考答案:
(1)s、c、i、d的偏移量分別為0、2、4、8,總共12字節;
(2)i、s、c、d的偏移量分別為0、4、6、7,總共8字節;
(3)c、s、i、d的偏移量分別為0、2、4、8,總共12字節;
(4)s、c的偏移量分別為0、6,總共8字節;
(5)c、s、i、d、e的偏移量分別為0、4、8、12、16,總共24字節;
(6)c、s、d的偏移量分別為0、36、40,總共44字節。
題目解析:
(1)s、c、i、d的偏移量分別為0、2、4、8,總共12字節;
(2)i、s、c、d的偏移量分別為0、4、6、7,總共8字節;
(3)c、s、i、d的偏移量分別為0、2、4、8,總共12字節;
(4)s、c的偏移量分別為0、6,總共8字節;
(5)c、s、i、d、e的偏移量分別為0、4、8、12、16,總共24字節;(6)c、s、d的偏移量分別為0、36、40,總共44字節。