[英]Disassembling IA32 32 bit AT&T assembly code of a function in C
[已編輯] 有人可以向我解釋我們如何在這個問題中獲得 M 和 N 的值,遍歷相應匯編代碼的每一行嗎?
我總是被 movl array2 部分難住。
M 和 N 是使用 #define 定義的常量
#define M <some value>
#define N <some value>
int array1[M][N];
int array2[N][M];
int copy(int i, int j)
{
array1[i][j] = array2[j][i];
}
如果上述代碼生成以下匯編代碼: 我們如何推導出常量 M 和 N 的值?
copy:
pushl %ebp
movl %esp, %ebp
pushl %ebx
movl 8(%ebp), %ecx
movl 12(%ebp), %ebx
leal (%ecx, %ecx, 8), %edx
sall $2, %edx
movl %ebx, %eax
sall $4, %eax
subl %ebx, %eax
sall $2, %eax
movl array2(%eax, %ecx, 4), %eax
movl %eax, array1(%edx, %ebx, 4)
popl %ebx
movl %ebp,%esp
popl %ebp
ret
您需要檢查組件的其他部分。 例如,如果您將 M 和 N 都定義為 8,您將在程序集中找到以下內容
array1:
.zero 256
array2:
.zero 256
因為在我的機器上,int 是 4 個字節,8 次 8 是 64。64 * 4 = 256。示例程序集可以在這里找到。
好吧,經過大量研究,我找到了解決方案。 如果我錯了,請糾正我。
因此,請逐步完成以下組裝:(為方便起見添加了行號)
M 和 N 是使用 #define 定義的常量
int array1[M][N];
int array2[N][M];
int copy(int i, int j)
{
array1[i][j] = array2[j][i];
}
copy:
1 pushl %ebp
2 movl %esp, %ebp
3 pushl %ebx
4 movl 8(%ebp), %ecx
5 movl 12(%ebp), %ebx
6 leal (%ecx, %ecx, 8), %edx
7 sall $2, %edx
8 movl %ebx, %eax
9 sall $4, %eax
10 subl %ebx, %eax
11 sall $2, %eax
12 movl array2(%eax, %ecx, 4), %eax
13 movl %eax, array1(%edx, %ebx, 4)
14 popl %ebx
15 movl %ebp,%esp
16 popl %ebp
ret
將%ebp
壓入堆棧
%ebp
指向%esp
將%ebx
壓入堆棧
%ecx
等於int i
(數組訪問的索引)
%ebx
等於int j
(數組訪問的索引)
%edx
等於8 * %ecx + %ecx
或9i
%edx
在二進制左移2
后等於36i
%eax
等於 %ebx 或j
%eax
左移二進制4
后等於16j
%eax
等於%eax - %ebx = 16j - j = 15j
%eax
左移2
后等於60j
%eax
等於下標為[4%ecx + %ebx] or [4i + 60j]
array2 元素
array1 的索引為[ 4%ebx + %edx ] or [ 4j + 36i ]
的元素等於%eax
或[4i + 60j]
使用 %eax 作為中間寄存器在 12 和 13 中完成的兩個數組元素的交換。
%ebx
彈出
%esp
的舊值已恢復
%ebp
彈出
現在我們假設array1[i][j]
的元素訪問等於4Ni + 4j
並且array2[j][i]
的元素訪問等於4Mj + 4i
。
(每個索引項中的 4 作為 int 是 4 個字節,i, j 是距起始數組位置的單獨偏移量)這是正確的,因為 C 以行主要形式存儲數組。
所以等價我們得到,M = 15 和 N = 9。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.