020 二维数组

/**************************020 二维数组*************************************
 * 打印出一个魔方阵,所谓魔方阵指的是每一行、每一列以及对角线之和均相等。
 * 方阵排列规则:
 * ⑴将1放在第一行中间一列;
 * ⑵从2开始直到n×n止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);
 * ⑶如果上一个数的行数为1,则下一个数的行数为n(指最下一行);例如1在第一行,则2应放在最下一行,列数同样加1;
 * ⑷当上一个数的列数为n时,下一个数的列数应为1,行数减去1。例如2在第3行最后一列,则3应放在第二行第一列;
 * ⑸如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面; 
 * C语言精彩编程百例,第20 */
#include <stdio.h>
void main()
{
	int array[16][16];
	int i,j,k,m,n;

	m=1;
	while(m==1)
	{
		printf("请输入n(0<n<15),n是奇数\n");
		scanf("%d",&n);

		if((n!=0)&&(n<=15)&&(n%2!=0))
		{
			printf("矩阵阶数是 %d\n",n);
			m=0;
		}
	}

	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			array[i][j]=0;

	j=n/2+1;
	array[1][j]=1;

	for(k=2;k<=n*n;k++)
	{
		i=i-1;
		j=j+1;
		if((i<1)&&(j>n))
		{
			i=i+2;
			j=j-1;
		}
		else
		{
			if(i<1) i=n;
			if(j>n) j=1;
		}
		if(array[i][j]==0)
			array[i][j]=k;
		else
		{
			i=i+2;
			j=j-1;
			array[i][j]=k;
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
			printf("%5d",array[i][j]);
		printf("\n");
	}
}

 

对应的汇编

	.file	"020.c"
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
LC0:
	.ascii "\307\353\312\344\310\353n(0<n<15),n\312\307\306\346\312\375\12\0"
LC1:
	.ascii "%d\0"
LC2:
	.ascii "\276\330\325\363\275\327\312\375\312\307 %d\12\0"
LC3:
	.ascii "%5d\0"
LC4:
	.ascii "\12\0"
	.align 2
.globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$1064, %esp         #光这个二位数组就站了16*16*4的空间
	andl	$-16, %esp
	movl	$0, %eax
	movl	%eax, -1056(%ebp)
	movl	-1056(%ebp), %eax
	call	__alloca
	call	___main
	movl	$1, -1048(%ebp)     #m=1
L4:
	cmpl	$1, -1048(%ebp)     # m==1
	je	L6
	jmp	L5
L6:
	subl	$12, %esp           # printf("请输入n(0<n<15),n是奇数\n");
	pushl	$LC0
	call	_printf
	addl	$16, %esp
	subl	$8, %esp            #scanf("%d",&n);
	leal	-1052(%ebp), %eax
	pushl	%eax
	pushl	$LC1
	call	_scanf
	addl	$16, %esp
	cmpl	$0, -1052(%ebp)     # n!=0
	je	L4
	cmpl	$15, -1052(%ebp)    # n<=15
	jg	L4
	movl	-1052(%ebp), %eax   # n是奇数
	andl	$1, %eax
	testl	%eax, %eax
	je	L4
	subl	$8, %esp
	pushl	-1052(%ebp)         # printf("矩阵阶数是 %d\n",n);
	pushl	$LC2
	call	_printf
	addl	$16, %esp
	movl	$0, -1048(%ebp)
	jmp	L4
L5:
	movl	$1, -1036(%ebp)     # i=1
L8:
	movl	-1036(%ebp), %eax   # i<=n
	cmpl	-1052(%ebp), %eax
	jle	L11
	jmp	L9
L11:
	movl	$1, -1040(%ebp)     # j=1
L12:
	movl	-1040(%ebp), %eax   # j<=n
	cmpl	-1052(%ebp), %eax
	jle	L15
	jmp	L10
L15:
	movl	-1036(%ebp), %eax      # eax=i                                       
	sall	$4, %eax               # eax=eax*16 (16是每行元素个数)
	addl	-1040(%ebp), %eax      # eax=j+i*16
	movl	$0, -1032(%ebp,%eax,4) # [ebp+eax*4-1032]=[ebp+(j+i*16)*4-1032] (4是 int占4个字节)
	leal	-1040(%ebp), %eax      # j++
	incl	(%eax)
	jmp	L12
L10:
	leal	-1036(%ebp), %eax      # i++
	incl	(%eax)
	jmp	L8
L9:
	movl	-1052(%ebp), %edx      # n 
	movl	%edx, %eax             # eax=edx
	sarl	$31, %eax              #算术右移,左侧用原符号位补齐
 	shrl	$31, %eax              #逻辑右移,左侧用0补齐,在最低位保留原来的符号位
  	leal	(%eax,%edx), %eax      # eax =eax + 原来的符号位
 	sarl	%eax                  # eax/2
	incl	%eax
	movl	%eax, -1040(%ebp)     # j=n/2+1
	movl	-1040(%ebp), %eax     # eax=j
	movl	$1, -968(%ebp,%eax,4) # [ebp+j*4-968]=[ebp+(j+1*16)*4-1032]=array[1][j] =1
	movl	$2, -1044(%ebp)       # k=2
L16:
	movl	-1052(%ebp), %eax     # eax=n
	imull	-1052(%ebp), %eax     # eax=n*n
	cmpl	%eax, -1044(%ebp)     # 比较k和n*n
	jle	L19
	jmp	L17
L19:
	leal	-1036(%ebp), %eax     # eax= &i
	decl	(%eax)                # i--
	leal	-1040(%ebp), %eax     # eax=&j
	incl	(%eax)                # j++
	cmpl	$0, -1036(%ebp)       # i 和 1-1 比较
	jg	L20
	movl	-1040(%ebp), %eax     # eax =j
	cmpl	-1052(%ebp), %eax     # j 和 n 比较
	jle	L20
	leal	-1036(%ebp), %eax     # eax =&i 
	addl	$2, (%eax)            # i =i+2
	leal	-1040(%ebp), %eax     # eax =&j
	decl	(%eax)                # j=j-1
	jmp	L21
L20:
	cmpl	$0, -1036(%ebp)       # i 和 1-1 比较
	jg	L22
	movl	-1052(%ebp), %eax     # eax =n
	movl	%eax, -1036(%ebp)     # i=n
L22:
	movl	-1040(%ebp), %eax     # eax=j
	cmpl	-1052(%ebp), %eax     # j 和 n 比较
	jle	L21
	movl	$1, -1040(%ebp)       # j=1
L21:
	movl	-1036(%ebp), %eax        # eax =i
	sall	$4, %eax                 # eax =i*16
	addl	-1040(%ebp), %eax        # eax=i*16+j
	cmpl	$0, -1032(%ebp,%eax,4)   # array[i][j]==0
	jne	L24
	movl	-1036(%ebp), %eax        # eax =i
	sall	$4, %eax                 # eax = i*16
	movl	%eax, %edx               # edx = i*16
	addl	-1040(%ebp), %edx        # edx = i*16+j
	movl	-1044(%ebp), %eax        # eax = k
	movl	%eax, -1032(%ebp,%edx,4) # array[i][j]==k
	jmp	L18
L24:
	leal	-1036(%ebp), %eax         # eax =&i
	addl	$2, (%eax)                # i =i+2
	leal	-1040(%ebp), %eax         # eax =&j
	decl	(%eax)                    # j=j-1
	movl	-1036(%ebp), %eax         # eax =i
	sall	$4, %eax                  # eax=i*16
	movl	%eax, %edx                # edx=i*16
	addl	-1040(%ebp), %edx         # edx=i*16+j
	movl	-1044(%ebp), %eax         # eax=k
	movl	%eax, -1032(%ebp,%edx,4)  # array[i][j]==k
L18:
	leal	-1044(%ebp), %eax         # eax=&k
	incl	(%eax)                    # k++
	jmp	L16
L17:
	movl	$1, -1036(%ebp)           # i=1
L26:
	movl	-1036(%ebp), %eax         # eax=i
	cmpl	-1052(%ebp), %eax         # 比较 i 和 n
	jle	L29
	jmp	L3
L29:
	movl	$1, -1040(%ebp)           # j=1
L30:
	movl	-1040(%ebp), %eax         # eax=j
	cmpl	-1052(%ebp), %eax         # 比较j和n
	jle	L33
	jmp	L31
L33:
	subl	$8, %esp                  # printf("%5d",array[i][j]);
	movl	-1036(%ebp), %eax         # eax =i
	sall	$4, %eax                  # eax =i*16
	addl	-1040(%ebp), %eax         # eax =j
	pushl	-1032(%ebp,%eax,4)        # array[i][j]
	pushl	$LC3
	call	_printf
	addl	$16, %esp
	leal	-1040(%ebp), %eax          # j++
	incl	(%eax)
	jmp	L30
L31:
	subl	$12, %esp                  #printf("\n");
	pushl	$LC4
	call	_printf
	addl	$16, %esp
	leal	-1036(%ebp), %eax
	incl	(%eax)
	jmp	L26
L3:
	leave
	ret
	.def	_scanf;	.scl	2;	.type	32;	.endef
	.def	_printf;	.scl	2;	.type	32;	.endef

 

二维数组特色的地方:

	movl	-1036(%ebp), %eax      # eax=i                                       
	sall	$4, %eax               # eax=eax*16 (16是每行元素个数)
	addl	-1040(%ebp), %eax      # eax=j+i*16
	movl	$0, -1032(%ebp,%eax,4) # [ebp+eax*4-1032]=[ebp+(j+i*16)*4-1032] (4是 int占4个字节)


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值