5.13 汇编语言:仿写For循环语句

lyshark
全栈领域优质创作者
博客专家认证
2023-11-18 13:09:44

循环语句(for)是计算机编程中的一种基本控制结构,它允许程序按照指定的次数或范围重复执行一段代码块。for循环在处理需要进行迭代操作的情况下非常有用,它使得程序可以更加方便地控制循环的次数。一般来说,for循环由三个部分组成:初始化部分、条件表达式和更新部分,以及一个需要重复执行的代码块。在每次循环迭代开始时,程序首先执行初始化部分,然后检查条件表达式的值,如果为真,则执行代码块,并在每次循环结束后执行更新部分。只要条件表达式为真,for循环就会一直重复执行;一旦条件表达式为假,循环将停止,程序继续执行循环之后的代码。

11.14 FOR 循环结构优化

For语句先初始化条件变量,然后在判断是否符合条件,符合则执行循环体,不符合则跳过执行。For循环结构的效率最低,该语句的构建往往需要三个跳转来实现,首先需要初始化变量此处要进行一次判断,其次是内部循环体需要另一个判断通常用于实现跳出循环体,最后一步则需要一个无条件跳转指令跳回到循环首地址,但在开启了O2优化时编译器也会尽可能将其转换为While语句,如果可以还会继续将While转为带有IF语句的Do循环来提高执行效率。

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

.data
  count DWORD ?
.code
  main PROC
    mov dword ptr ds:[count],0          ; 设置 int x = 0;
    jmp L2

  L1:
    mov eax,dword ptr ds:[count]        ; x = x++
    add eax,1
    mov dword ptr ds:[count],eax

  L2:
    cmp dword ptr ds:[count],10         ; 比较 x < 10
    jge lop_end
    
    xor eax,eax                         ; 执行循环体
    jmp L1
    
  lop_end:
    int 3
    invoke ExitProcess,0
  main ENDP
END main

虽然For语句在执行效率上来说是最低的,但该语句的使用确是最符合我们思维方式的,在高级语言中应用最为广泛,例如在Python中For循环体被简化成了for x in range(2,10)它可以指定一个循环范围,该语句利用汇编完全也可以被构建出来,我们接着尝试构建一下这个特别的循环体。

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

.data
  start_count DWORD ?
  end_count DWORD ?
.code
  main PROC
    mov dword ptr ds:[start_count],2     ; 指定开始循环编号
    mov dword ptr ds:[end_count],5       ; 指定结束循环编号
    
    mov ecx,dword ptr ds:[start_count]
  L1:
    cmp dword ptr ds:[end_count],ecx
    jle lop_end
    
    xor eax,eax                          ; 循环体内部
    
    add ecx,1                            ; 每次递增
    mov dword ptr ds:[start_count],ecx
    jmp L1
    
  lop_end:
    int 3
    invoke ExitProcess,0
  main ENDP
END main

11.20 仿写For水仙花数

该C++代码实现了水仙花数的查找算法,水仙花数是指一个三位数,它的每个位上的数字的立方和等于它本身。在循环中,遍历100~999之间的每一个数,将其分解为三个数(百、十、个位),再将三个数分别平方并相加,判断与原数是否相等,如果相等则输出该数即为水仙花数。

  • 例如: 153是一个水仙花数,因为153等于1的3次方加上5的3次方加上3的3次方
#include <stdio.h>
#include <Windows.h>

int main(int argc, char *argv[])
{
  int x, y, z, n;
  for (n = 100; n < 1000; n++)
  {
    x = n / 100;          // 分解百位
    y = n / 10 % 10;      // 分解十位
    z = n % 10;           // 分解个位
    if (x * 100 + y * 10 + z == x*x*x + y*y*y + z*z*z)
    {
      printf("水仙花: %-5d \n", n);
    }
  }

  system("pause");
  return 0;
}

尝试使用汇编实现计算逻辑,这段代码没有任何难度,因为并不会涉及到嵌套循环的问题,只是在计算四则运算时需要格外注意些。

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  x DWORD ?
  y DWORD ?
  z DWORD ?
  n DWORD ?
  szFmt BYTE '水仙花: %-5d ',0dh,0ah,0

.code
  main PROC
    mov dword ptr ds:[n],100     ; n = 100
    jmp L1
  L2: mov eax,dword ptr ds:[n]
    add eax,1                    ; n++
    mov dword ptr ds:[n],eax
  L1: mov eax,dword ptr ds:[n]
    cmp eax,1000                 ; n < 1000
    jge lop_end
    
    mov eax,dword ptr ds:[n]
    cdq
    mov ecx,100                  ; x = n / 100;
    idiv ecx
    mov dword ptr ds:[x],eax
    
    mov eax,dword ptr ds:[n]
    cdq
    mov ecx,10
    idiv ecx                     ; y = n / 10;
    cdq
    mov ecx,10
    idiv ecx                     ; y = y % 10;
    mov dword ptr ds:[y],edx
    
    mov eax,dword ptr ds:[n]
    cdq
    mov ecx,10
    idiv ecx                     ; z = n % 10;
    mov dword ptr ds:[z],edx
    
    ; 开始执行if()比较语句
    imul eax,dword ptr ds:[x],100  ; x * 100
    imul ecx,dword ptr ds:[y],10   ; y * 10
    add eax,dword ptr ds:[z]       ; + z
    add ecx,eax
    
    mov edx,dword ptr ds:[x]
    imul edx,dword ptr ds:[x]      ; x*x*x
    imul edx,dword ptr ds:[x]
    
    mov eax,dword ptr ds:[y]
    imul eax,dword ptr ds:[y]      ; y*y*y
    imul eax,dword ptr ds:[y]
    add edx,eax
    
    mov eax,dword ptr ds:[z]
    imul eax,dword ptr ds:[z]      ; z*z*z
    imul eax,dword ptr ds:[z]
    add edx,eax
    
    cmp ecx,edx   ; (x * 100 + y * 10 + z) == (x*x*x + y*y*y + z*z*z)
    jne L2
    
    mov eax,dword ptr ds:[n]
    invoke crt_printf,addr szFmt,eax
    jmp L2
    
  lop_end:
    int 3 

  main ENDP
END main

11.21 For循环尝试判断

该C++代码实现了一个简单的循环,遍历数组中的所有元素并输出大于等于50的元素。在循环中,通过判断Array数组中每个元素与50的大小关系,如果元素大于等于50,则使用printf函数输出该元素的值。最终程序输出所有大于等于50的元素。

#include <stdio.h>
#include <Windows.h>

int main(int argc,char *argv[])
{
  int Array[10] = { 56,78,33,45,78,90,32,44,56,67 };

  for (int x = 0; x < 10; x++)
  {
    if (Array[x] >= 50)
    {
      printf("out -> %d \n", Array[x]);
    }
  }
  return 0;
}

上述C语言代码如果通过汇编语言实现可以写成如下样子,读者可自行理解流程;

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  MyArray DWORD 56,78,33,45,78,90,32,44,56,67
  count DWORD ?
  szFmt BYTE 'out -> %d ',0dh,0ah,0

.code
  main PROC
    
    mov dword ptr ds:[count],0      ; int x = 0
    jmp L1
  L2: mov eax,dword ptr ds:[count]
    add eax,1                       ; x ++
    mov dword ptr ds:[count],eax
  L1:
    cmp dword ptr ds:[count],10     ; x < 10
    jge lop_end
    
    mov eax,dword ptr ds:[count]          ; 获取循环次数,当作因子
    lea esi,dword ptr ds:[MyArray]        ; 取数组基地址
    mov ebx,dword ptr ds:[esi + eax * 4]  ; 因子寻址
    cmp ebx,50
    jl L2                                 ; 如果小于50则跳转到下一次循环
    
    invoke crt_printf,addr szFmt,ebx      ; 调用系统crt
    jmp L2

  lop_end:
    int 3
  
    invoke ExitProcess,0
  main ENDP
END main

在读者学会了上述代码编写之后,我们继续增加代码的复杂度,如下所示代码实现了对整型数组的最大值、最小值、元素总和以及平均值的计算。在循环中,通过依次遍历数组中的每一个元素,维护一个当前最大值max_result和最小值min_result,并对元素进行累加求和,最终计算出数组中所有元素的平均值avg_result。代码中使用printf函数输出求得的四个值(max、min、sum、avg),并使用system函数暂停程序以便观察输出结果。

#include <stdio.h>
#include <Windows.h>

int main(int argc, char *argv[])
{
  int Array[10] = { 56,78,33,45,78,90,32,44,56,67 };
  int max_result = 0,min_result = 100,sum_result = 0,avg_result = 0;

  for (int x = 0; x < 10; x++)
  {
    if (Array[x] >= max_result)
    {
      max_result = Array[x];
    }
    if (Array[x] <= min_result)
    {
      min_result = Array[x];
    }
    sum_result = sum_result + Array[x];
    avg_result = sum_result / 10;
  }
  printf("max = %d min = %d sum = %d avg = %d \n", max_result,min_result,sum_result,avg_result);
  system("pause");
  return 0;
}

上述代码读者可尝试使用汇编语言来实现一下,如下代码是笔者思考后编写出来的实现流程,读者可自行对照参考;

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  MyArray DWORD 56,78,33,45,78,90,32,44,56,67
  count DWORD ?
  max_result DWORD 0
  min_result DWORD 100
  sum_result DWORD 0
  avg_result DWORD 0
  
  szFmt BYTE 'max = %d min= %d sum= %d avg = %d ',0dh,0ah,0

.code
  main PROC
    mov dword ptr ds:[count],0      ; int x = 0
    jmp L1
  L2: mov eax,dword ptr ds:[count]
    add eax,1                       ; x ++
    mov dword ptr ds:[count],eax
  L1:
    cmp dword ptr ds:[count],10     ; x < 10
    jge lop_end

    mov eax,dword ptr ds:[count]
    lea esi,dword ptr ds:[MyArray]
    
    mov ebx,dword ptr ds:[esi + eax * 4]
    cmp ebx,dword ptr ds:[max_result]      ; Array[x] >= max_result
    jl L3
    mov dword ptr ds:[max_result],ebx      ; max_result = Array[x];
  L3:
    mov ebx,dword ptr ds:[esi + eax * 4]
    cmp ebx,dword ptr ds:[min_result]      ; Array[x] <= min_result
    jg L4
    mov dword ptr ds:[min_result],ebx

  L4:
    mov ebx,dword ptr ds:[esi + eax * 4]   ; Array[x]
    add dword ptr ds:[sum_result],ebx      ; sum_result = sum_result + Array[x];
    
    mov eax,dword ptr ds:[sum_result]
    cdq                                    ; 符号扩展
    mov ecx,10                             ; / 10
    idiv ecx                               ; sum_result / 10;
    mov dword ptr ds:[avg_result],eax      ; avg_result
    jmp L2
    
  lop_end:
    mov eax,dword ptr ds:[max_result]
    mov ebx,dword ptr ds:[min_result]
    mov ecx,dword ptr ds:[sum_result]
    mov edx,dword ptr ds:[avg_result]
    invoke crt_printf,addr szFmt,eax,ebx,ecx,edx
    int 3
  main ENDP
END main

11.22 For循环多重IF判断

该C++代码实现了对两个数组进行元素相加,并输出相加结果的奇偶性。在循环中,对SrcArrayDstArray两个数组中的元素相加,如果两个元素均不为0,则判断相加的结果是否为偶数,如果是,则使用printf函数输出偶数sum的形式,否则输出基数sum的形式。其中sum表示两个元素相加的结果。代码中使用system函数暂停程序以便观察输出结果。

#include <stdio.h>
#include <Windows.h>

int main(int argc, char *argv[])
{
  int SrcArray[10] = { 56,78,33,45,78,90,32,15,56,67 };
  int DstArray[10] = { 59,77,89,23,11,45,67,88,93,27 };
  int index = 0;

  for (index = 0; index < 10; index++)
  {
    if (SrcArray[index] != 0 && DstArray[index] != 0)
    {
      int sum = SrcArray[index] + DstArray[index];
      if (sum % 2 == 0)
        printf("偶数: %d \n", sum);
      else
        printf("基数: %d \n", sum);
    }
  }
  system("pause");
  return 0;
}

上述代码片段的逻辑并不复杂,仅仅只是循环内部嵌套双层判断,笔者思考片刻后即写出了与之对应的汇编代码;

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  SrcArray DWORD 56,78,33,45,78,90,32,15,56,67
  DstArray DWORD 59,77,89,23,11,45,67,88,93,27
  index DWORD 0
  sum DWORD 0
  
  szFmt1 BYTE '基数: %d ',0dh,0ah,0
  szFmt2 BYTE '偶数: %d ',0dh,0ah,0

.code
  main PROC
    mov dword ptr ds:[index],0        ; index = 0
    
    jmp L1
  L2: mov eax,dword ptr ds:[index]
    add eax,1                         ; index++
    mov dword ptr ds:[index],eax
  L1:
    cmp dword ptr ds:[index],10       ; index < 10
    jge lop_end
    
    mov eax,dword ptr ds:[index];
    cmp dword ptr ds:[SrcArray + eax * 4],0
    je L2                                     ; SrcArray[index] != 0
    
    mov eax,dword ptr ds:[index]
    cmp dword ptr ds:[DstArray + eax * 4],0   ; DstArray[index] != 0
    je L2
    
    ; ------------------------------------------
    ; 另类加法,通过一个SrcArray定位DstArray完成加法
    
    mov eax,dword ptr ds:[index]                 ; 获取因子
    lea esi,dword ptr ds:[SrcArray]              ; 取数组首地址
    
    mov ebx,dword ptr ds:[esi + eax * 4]         ; 获取 SrcArray[index]
    mov ecx,dword ptr ds:[esi + eax * 4 + 40]    ; 获取 DstArray[index]
    add ebx,ecx                                  ; SrcArray[index] + DstArray[index]
    mov dword ptr ds:[sum],ebx                   ; sum = SrcArray[index] + DstArray[index]
    
    mov eax,dword ptr ds:[sum]
    and eax,080000001h                           ; sum % 2 == 0
    test eax,eax
    jne L3
    
    invoke crt_printf,addr szFmt2,dword ptr ds:[sum]  ; 偶数输出
    jmp L2
  L3:
    invoke crt_printf,addr szFmt1,dword ptr ds:[sum]  ; 基数输出
    jmp L2
  lop_end:
    int 3

  main ENDP
END main

11.23 For嵌套乘法口诀表

该C++代码实现了乘法口诀表的打印。在两个for循环中,分别对x和y进行遍历,对每一次的遍历输出一个乘法口诀表的元素。代码中使用printf函数实现输出,并使用\n进行换行。程序遍历打印了从11到99的所有乘积的结果,这就是乘法口诀表。

#include <stdio.h>
#include <Windows.h>

int main(int argc, char *argv[])
{
  for (int x = 1; x < 10; x++)
  {
    for (int y = 1; y <= x; y++)
    {
      int result = x*y;
      printf("%d*%d=%-3d", y, x, result);
    }
    printf("\n");
  }
  system("pause");
  return 0;
}

乘法口诀表的实现方法只需要嵌套两层FOR循环语句,在使用汇编语言实现之前我们可以先来构建出这个双层循环体,如下代码所示;

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  x DWORD ?
  y DWORD ?
  szFmt BYTE '内层循环: %d 外层循环: %d ',0dh,0ah,0
  szPr  BYTE '----->',0dh,0ah,0

.code
  main PROC
    mov dword ptr ds:[x],1        ; int x = 1
    jmp L1
  L2: mov eax,dword ptr ds:[x]
    add eax,1                     ; x++
    mov dword ptr ds:[x],eax
  L1: 
    cmp dword ptr ds:[x],10       ; x < 10
    jge lop_end

    mov dword ptr ds:[y],1        ; y = 1
    jmp L3
  L5: mov eax,dword ptr ds:[y]
    add eax,1                     ; y++
    mov dword ptr ds:[y],eax
  L3:
    mov eax,dword ptr ds:[y]
    cmp eax,dword ptr ds:[x]      ; y <= x
    jg L4
    
    ; 执行的是循环体内部
    mov eax,dword ptr ds:[x]
    mov ebx,dword ptr ds:[y]
    invoke crt_printf,addr szFmt,eax,ebx
    
    jmp L5
  L4:
    ; 执行外层循环
    invoke crt_printf,addr szPr

    jmp L2
  lop_end:
    int 3

  main ENDP
END main

当有了双层循环体结构之后,我们只需要再其循环之上增加一个乘法计算功能即可,完整的计算流程如下所示;

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  x DWORD ?
  y DWORD ?
  szFmt BYTE '%d * %d = %d ',0
  szPr  BYTE ' ',0dh,0ah,0
.code
  main PROC
    mov dword ptr ds:[x],1        ; int x = 1
    jmp L1
  L2: mov eax,dword ptr ds:[x]
    add eax,1                     ; x++
    mov dword ptr ds:[x],eax
  L1: 
    cmp dword ptr ds:[x],10       ; x < 10
    jge lop_end

    mov dword ptr ds:[y],1        ; y = 1
    jmp L3
  L5: mov eax,dword ptr ds:[y]
    add eax,1                     ; y++
    mov dword ptr ds:[y],eax
  L3:
    mov eax,dword ptr ds:[y]
    cmp eax,dword ptr ds:[x]      ; y <= x
    jg L4
    
    ; 执行的是循环体内部
    mov eax,dword ptr ds:[x]
    imul eax,dword ptr ds:[y]
    invoke crt_printf,addr szFmt,dword ptr ds:[y],dword ptr ds:[x],eax
    
    jmp L5
  L4:
    ; 执行外层循环
    invoke crt_printf,addr szPr

    jmp L2
  lop_end:
    int 3

  main ENDP
END main

11.24 For语句冒泡排序

该C++代码实现了冒泡排序算法对整型数组进行排序。在冒泡排序算法中,数组中每两个相邻的元素,如果前一个元素大于后一个元素,则交换这两个元素的位置。循环遍历数组多次,每次将未排序的最大值向数组末尾冒泡,直到数组中的所有元素都排好序。代码中使用两层for循环实现排序,内层循环从数组末尾开始,逐步向前遍历,交换相邻的两个元素。外层循环控制排序的遍历次数,只有在当前相邻两个数未排序时才进行交换。程序最终输出排序后的数组。

#include <stdio.h>
#include <Windows.h>

int main(int argc, char *argv[])
{
  int Array[10] = { 34,78,65,77,89,43,23,55,67,8 };
  int x, y, temporary, ArraySize=10;

  for (x = 0; x < ArraySize - 1; x++)
  {
    for (y = ArraySize - 1; y > x; y--)
    {
      if (Array[y - 1] > Array[y])
      {
        temporary = Array[y - 1];
        Array[y - 1] = Array[y];
        Array[y] = temporary;
      }
    }
  }

  for (int x = 0; x < 10; x++)
  {
    printf("%d \n", Array[x]);
  
  system("pause");
  return 0;
}

由于冒泡排序牵扯到了数据交换所以汇编版本可能稍显负责,不过大体框架还是没有脱离二层循环,仅仅只是在二层循环内部增加了一个判断流程而已,其实如果认真构建相信读者也可以很容易的写出来。

  .386p
  .model flat,stdcall
  option casemap:none

include windows.inc
include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
  Array DWORD 34,78,65,77,89,43,23,55,67,8
  x DWORD ?
  y DWORD ?
  Temporary DWORD ?
  ArraySize DWORD ?
  szFmt BYTE '%d --> %d ',0dh,0ah,0

.code
  main PROC
    ; 初始化的部分
    mov dword ptr ds:[x],0            ; x=0
    mov dword ptr ds:[ArraySize],10   ; ArraySize=10
    
    ; 外层循环体
    jmp L1
  L2: mov eax,dword ptr ds:[x]
    add eax,1                          ; x++
    mov dword ptr ds:[x],eax
    
  L1: mov eax,dword ptr ds:[ArraySize]
    sub eax,1                          ; ArraySize - 1
    cmp dword ptr ds:[x],eax           ; x < ArraySize
    jge lop_end
    
    ; 内层循环体内容
    mov eax,dword ptr ds:[ArraySize]
    sub eax,1
    mov dword ptr ds:[y],eax
    
    jmp L3
  L4: mov eax,dword ptr ds:[y]
    sub eax,1                           ; y--
    mov dword ptr ds:[y],eax
  
  L3: mov eax,dword ptr ds:[y]
    cmp eax,dword ptr ds:[x]            ; Array[y - 1] > Array[y]
    jle L2
    
    ; 寻址y和y-1的位置
    mov esi,dword ptr ds:[y]

    mov ebx,dword ptr ds:[Array + esi * 4]         ; Array[y]
    mov edx,dword ptr ds:[Array + esi * 4 - 4]     ; Array[y - 1]
    cmp edx,ebx
    jle L4
    
    ; 数据交换
    mov dword ptr ds:[Array + esi * 4],edx         ; Array[y] = Array[y - 1]
    mov dword ptr ds:[Array + esi * 4 - 4],ebx     ; Array[y - 1] = Array[y]
    ; invoke crt_printf,addr szFmt,ebx,edx
    
    jmp L4
    jmp L2

  lop_end:
    nop

    ; 执行打印函数
    mov dword ptr ds:[Temporary],0

    jmp L5
  L7: mov eax,dword ptr ds:[Temporary]
    add eax,1
    mov dword ptr ds:[Temporary],eax
  L5:
    mov eax,dword ptr ds:[Temporary]
    cmp eax,10
    jge L6
    
    lea esi,dword ptr ds:[Array]                ; 取数组基地址
    mov esi,dword ptr ds:[Array + eax * 4]      ; 比例因子寻址
    invoke crt_printf,addr szFmt,esi,esi
    jmp L7
  L6:
    int 3

  main ENDP
END main

至此,汇编中的循环结构仿写就告一段落了,笔者提醒大家,由于汇编难度较大,且代码都是线性的,所以在编写之前要分析好主次关系,当有了主次关系之后,我们就需要静下心来,一个个构建,由外到内步步为营,其实汇编也并不是那么可怕。

...全文
19 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(HelloAndroid!) 2.3 Android应用程序架构——从此开始 2.4 可视化的界面开发工具 2.5 部署应用程序到Android手机 第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——CharSequence数据类型与ResourceID应用 3.5 取得手机屏幕大小——DisplayMetrics取得画面宽高的方法 3.6 样式化的定型对象——Style样式的定义 3.7 简易的按钮事件——Button事件处理 3.8 手机页面的转换——setContentView的应用 3.9 调用另一个Activity——Intent对象的使用 3.10 不同Activity之间的数据传递——Bundle对象的实现 3.11 返回数据到前一个Activity——startActivityForResult方法 3.12 具有交互功能的对话框——AlertDialog窗口 3.13 置换文字颜色的机关——Button与TextView的交互 3.14 控制不同的文字字体——Typeface对象使用 3.15 如iPhone拖动相片特效——Gallery画廊 3.16 自制计算器——多按钮的整合应用 3.17 关于(About)程序信息——Menu功能菜单程序设计 3.18 程序加载中,请稍后——ProgressDialog与线程整合应用 3.19 全屏幕以按钮覆盖——动态产生按钮并最大化 3.20 今晚到哪儿打牙祭?——具选择功能的对话框 3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast对象的使用 4.4 我同意条款——CheckBox的isChecked属性 4.5 消费券采购列表——多选项CheckBox的应用 4.6 向左或向右——RadioGroup组与onCheckedChanged事件 4.7 专业相框设计——ImageView的堆栈应用 4.8 自定义下拉菜单模式——Spinner与setDropDownViewResource 4.9 动态添加/删除的Spinner菜单——ArrayList与Widget的依赖性 4.10 心爱小宝贝相片集——Gallery与衍生BaseAdapter容器 4.11 快速的搜索手机文件引擎——JavaI/O的应用 4.12 按钮也能随点击变换——ImageButton选择特效 4.13 具自动提示功能的菜单——AutoCompleteTextView与数组 4.14 数字及模拟小时钟设计——AnalogClock与DigitalClock的原理 4.15 动态输入日期与时间——DatePicker与TimePicker应用 4.16 猜猜红心A在那儿——ImageView点击事件与透明度处理 4.17 后台程序运行进度提示——ProgressBar与Handler的整合应用 4.18 动态文字排版——GridView与ArrayAdapter设计 4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与Menu整合技巧 4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——Bitmap与Matrix旋转ImageView 4.25 猜猜我在想什么——RadioButtonID 4.26 离开与关闭程序的弹出窗口——对话窗口上的ICON图标 第5章 交互式通信服务与手机控制 5.1 具有正则表达式的TextView——Linkify规则 5.2 ACTION!CALL!拨打电话——Intent
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(HelloAndroid!) 2.3 Android应用程序架构——从此开始 2.4 可视化的界面开发工具 2.5 部署应用程序到Android手机 第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——CharSequence数据类型与ResourceID应用 3.5 取得手机屏幕大小——DisplayMetrics取得画面宽高的方法 3.6 样式化的定型对象——Style样式的定义 3.7 简易的按钮事件——Button事件处理 3.8 手机页面的转换——setContentView的应用 3.9 调用另一个Activity——Intent对象的使用 3.10 不同Activity之间的数据传递——Bundle对象的实现 3.11 返回数据到前一个Activity——startActivityForResult方法 3.12 具有交互功能的对话框——AlertDialog窗口 3.13 置换文字颜色的机关——Button与TextView的交互 3.14 控制不同的文字字体——Typeface对象使用 3.15 如iPhone拖动相片特效——Gallery画廊 3.16 自制计算器——多按钮的整合应用 3.17 关于(About)程序信息——Menu功能菜单程序设计 3.18 程序加载中,请稍后——ProgressDialog与线程整合应用 3.19 全屏幕以按钮覆盖——动态产生按钮并最大化 3.20 今晚到哪儿打牙祭?——具选择功能的对话框 3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast对象的使用 4.4 我同意条款——CheckBox的isChecked属性 4.5 消费券采购列表——多选项CheckBox的应用 4.6 向左或向右——RadioGroup组与onCheckedChanged事件 4.7 专业相框设计——ImageView的堆栈应用 4.8 自定义下拉菜单模式——Spinner与setDropDownViewResource 4.9 动态添加/删除的Spinner菜单——ArrayList与Widget的依赖性 4.10 心爱小宝贝相片集——Gallery与衍生BaseAdapter容器 4.11 快速的搜索手机文件引擎——JavaI/O的应用 4.12 按钮也能随点击变换——ImageButton选择特效 4.13 具自动提示功能的菜单——AutoCompleteTextView与数组 4.14 数字及模拟小时钟设计——AnalogClock与DigitalClock的原理 4.15 动态输入日期与时间——DatePicker与TimePicker应用 4.16 猜猜红心A在那儿——ImageView点击事件与透明度处理 4.17 后台程序运行进度提示——ProgressBar与Handler的整合应用 4.18 动态文字排版——GridView与ArrayAdapter设计 4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与Menu整合技巧 4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——Bitmap与Matrix旋转ImageView 4.25 猜猜我在想什么——RadioButtonID 4.26 离开与关闭程序的弹出窗口——对话窗口上的ICON图标 第5章 交互式通信服务与手机控制 5.1 具有正则表达式的TextView——Linkify规则 5.2 ACTION!CALL!拨打电话——Intent.ACTION.CALL的使用 5.3 自制发送短信程序——SmsManager与PendingIntent对象 5.4 自制发送Email程序——Intent在Email上的使用 5.5 自制日历手机数据库——实现SQLiteOpenHelper 5.6 手机震动的节奏——Vibrator对象及周期运用 5.7 图文可视化提醒——Toast与LinearLayoutView 5.8 状态栏的图标与文字提醒——NotificationManager与Notification对象的应用 5.9 搜索手机通讯录自动完成——使用ContentResolver 5.10 取得联系人资料——Provider.Contact的使用 5.11 制作有图标的文件资源管理器——自定义Adapter对象 5.12 还原手机默认桌面——重写clearWallpaper方法 5.13 置换手机背景图——Gallery与setWallpaper整合实现 5.14 撷取手机现存桌面——getWallpaper与setImageDrawable 5.15 文件资源管理器再进化——JavaI/O修改文件名及删除 5.16 取得目前File与Cache的路径——getCacheDir与getFilesDir 5.17 打开/关闭WiFi服务——WifiManager状态判断 5.18 取得SIM卡内的信息——TelephonyManager的应用 5.19 调用拨号按钮——打电话CALL_BUTTON 5.20 DPAD按键处理——onKeyDown事件与Layout坐标交互 5.21 任务管理器正在运行的程序——RunningTaskInfo 5.22 动态更改屏幕方向——LANDSCAPE与PORTRAIT 5.23 系统设置更改事件——onConfigurationChanged信息处理 5.24 取得电信网络与手机相关信息——TelephonyManager与android.provider.Settings.System的应用 第6章 手机自动服务纪实 6.1 您有一条短信popup提醒——常驻BroadcastReceiver的应用 6.2 手机电池计量还剩多少——使用BroadcastReceiver捕捉Intent.ACTION_BATTERY_CHANGED 6.3 群发拜年短信给联系人——ACTION_PICK与Uri对象 6.4 开始与停止系统服务——Service与Runnable整合并用 6.5 通过短信发送email通知——BroadcastReceiver与Intent整合 6.6 手机拨接状态——PhoneStateListener之onCallStateChanged 6.7 有来电,发送邮件通知——PhoneStateListener与ACTION_SEND 6.8 存储卡剩余多少容量——Environment加StatFs 6.9 访问本机内存与存储卡——File的创建与删除 6.10 实现可定时响起的闹钟——PendingIntent与AlarmManager的运用 6.11 黑名单来电自动静音——PhoneStateListener与AudioManager 6.12 手机翻背面即静音震动——SensorListener及AudioManager整合应用 6.13 指定时间置换桌面背景——多AlarmManager事件处理 6.14 判断发送短信后的状态——BroadcastReceiver聆听PendingIntent 6.15 后台服务送出广播信息——sendBroadcast与BroadcastReceiver 6.16 开机程序设计——receiver与intent-filter协同作业 6.17 双向短信常驻服务——Service与receiver实例 第7章 娱乐多媒体 7.1 访问Drawable资源的宽高——ContextMenu与Bitmap的应用 7.2 绘制几何图形——使用android.graphics类 7.3 手机屏幕保护程序——FadeIn/FadeOut特效与运行线程 7.4 用手指移动画面里的照片——onTouchEvent事件判断 7.5 加载存储卡的Gallery相簿——FileArrayList 7.6 取得手机内置媒体里的图文件——ACTION_GET_CONTENT取回InputStream 7.7 相片导航向导与设置背景桌面——ImageSwitcher与Gallery 7.8 调整音量大小声——AudioManager控制音量 7.9 播放mp3资源文件——raw文件夹与MediaPlayer的使用 7.10 播放存储卡里的mp3音乐——MediaPlayer.setDataSource 7.11 自制录音/播放录音程序——MediaRecorder与AudioEncoder 7.12 通过收到短信开始秘密录音——MediaRecorder与BroadcastReceiver实例 7.13 内置影片播放器载入3gp电影——VideoViewWidget 7.14 自制3gp影片播放器——MediaPlayer与实现SurfaceView 7.15 相机预览及拍照临时文件——Camera及PictureCallback事件 第8章 当Android与Internet接轨 8.1 HTTPGET/POST传递参数——HTTP连接示范 8.2 在程序里浏览网页——WebView.loadUrl 8.3 嵌入HTML标记的程序——WebView.loadData 8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery中显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——HttpURLConnection与URLConnection和运行线程 8.8 通过网络播放MP3——Runnable存储FileOutputStream技巧 8.9 设置远程下载音乐为手机铃声——RingtoneManager与铃声存放路径 8.10 远程下载桌面背景图案——URLConnection与setWallpaper()搭配 8.11 将手机文件上传至网站服务器——模拟HTTPFORM的POSTACTION 8.12 移动博客发布器——以XML-RPC达成远程过程调用 8.13 移动RSS阅读器——利用SAXParser解析XML 8.14 远程下载安装Android程序——APKInstaller的应用 8.15 手机下载看3gp影片——Runnable混搭SurfaceView 8.16 访问网站LoginAPI——远程服务器验证程序运行权限 8.17 地震速报!——HttpURLConnection与Service侦测服务 第9章 Google服务与Android混搭 9.1 Google帐号验证Token——AuthSub 9.2 Google搜索——AutoCompleteTextView与GoogleSearchAPI 9.3 前端产生QRCode二维条形码——GoogleChartAPI 9.4 以经纬度查找目的地位置——GeoPoint与MapView的搭配运用 9.5 GPSGoogle地图——LocationListener与MapView实时更新 9.6 移动版GoogleMap——Geocoder反查Address对象 9.7 规划导航路径——DirectionsRoute 9.8 移动设备上的Picasa相册——GooglePicasaAPI 9.9 随身翻译机——GoogleTranslateAPI 第10章 创意Android程序设计 10.1 手机手电筒——PowerManager控制WakeLock并改变手机亮度 10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode二维条形码扫描仪——BitmapFactory.decodeByteArray 10.6 上班族今天中午要吃什么——热量骰子地图 10.7 掷杯筊——把手机放在空中甩事件处理...
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(HelloAndroid!) 2.3 Android应用程序架构——从此开始 2.4 可视化的界面开发工具 2.5 部署应用程序到Android手机 第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——CharSequence数据类型与ResourceID应用 3.5 取得手机屏幕大小——DisplayMetrics取得画面宽高的方法 3.6 样式化的定型对象——Style样式的定义 3.7 简易的按钮事件——Button事件处理 3.8 手机页面的转换——setContentView的应用 3.9 调用另一个Activity——Intent对象的使用 3.10 不同Activity之间的数据传递——Bundle对象的实现 3.11 返回数据到前一个Activity——startActivityForResult方法 3.12 具有交互功能的对话框——AlertDialog窗口 3.13 置换文字颜色的机关——Button与TextView的交互 3.14 控制不同的文字字体——Typeface对象使用 3.15 如iPhone拖动相片特效——Gallery画廊 3.16 自制计算器——多按钮的整合应用 3.17 关于(About)程序信息——Menu功能菜单程序设计 3.18 程序加载中,请稍后——ProgressDialog与线程整合应用 3.19 全屏幕以按钮覆盖——动态产生按钮并最大化 3.20 今晚到哪儿打牙祭?——具选择功能的对话框 3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast对象的使用 4.4 我同意条款——CheckBox的isChecked属性 4.5 消费券采购列表——多选项CheckBox的应用 4.6 向左或向右——RadioGroup组与onCheckedChanged事件 4.7 专业相框设计——ImageView的堆栈应用 4.8 自定义下拉菜单模式——Spinner与setDropDownViewResource 4.9 动态添加/删除的Spinner菜单——ArrayList与Widget的依赖性 4.10 心爱小宝贝相片集——Gallery与衍生BaseAdapter容器 4.11 快速的搜索手机文件引擎——JavaI/O的应用 4.12 按钮也能随点击变换——ImageButton选择特效 4.13 具自动提示功能的菜单——AutoCompleteTextView与数组 4.14 数字及模拟小时钟设计——AnalogClock与DigitalClock的原理 4.15 动态输入日期与时间——DatePicker与TimePicker应用 4.16 猜猜红心A在那儿——ImageView点击事件与透明度处理 4.17 后台程序运行进度提示——ProgressBar与Handler的整合应用 4.18 动态文字排版——GridView与ArrayAdapter设计 4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与Menu整合技巧 4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——Bitmap与Matrix旋转ImageView 4.25 猜猜我在想什么——RadioButtonID 4.26 离开与关闭程序的弹出窗口——对话窗口上的ICON图标 第5章 交互式通信服务与手机控制 5.1 具有正则表达式的TextView——Linkify规则 5.2 ACTION!CALL!拨打电话——Intent.ACTION.CALL的使用 5.3 自制发送短信程序——SmsManager与PendingIntent对象 5.4 自制发送Email程序——Intent在Email上的使用 5.5 自制日历手机数据库——实现SQLiteOpenHelper 5.6 手机震动的节奏——Vibrator对象及周期运用 5.7 图文可视化提醒——Toast与LinearLayoutView 5.8 状态栏的图标与文字提醒——NotificationManager与Notification对象的应用 5.9 搜索手机通讯录自动完成——使用ContentResolver 5.10 取得联系人资料——Provider.Contact的使用 5.11 制作有图标的文件资源管理器——自定义Adapter对象 5.12 还原手机默认桌面——重写clearWallpaper方法 5.13 置换手机背景图——Gallery与setWallpaper整合实现 5.14 撷取手机现存桌面——getWallpaper与setImageDrawable 5.15 文件资源管理器再进化——JavaI/O修改文件名及删除 5.16 取得目前File与Cache的路径——getCacheDir与getFilesDir 5.17 打开/关闭WiFi服务——WifiManager状态判断 5.18 取得SIM卡内的信息——TelephonyManager的应用 5.19 调用拨号按钮——打电话CALL_BUTTON 5.20 DPAD按键处理——onKeyDown事件与Layout坐标交互 5.21 任务管理器正在运行的程序——RunningTaskInfo 5.22 动态更改屏幕方向——LANDSCAPE与PORTRAIT 5.23 系统设置更改事件——onConfigurationChanged信息处理 5.24 取得电信网络与手机相关信息——TelephonyManager与android.provider.Settings.System的应用 第6章 手机自动服务纪实 6.1 您有一条短信popup提醒——常驻BroadcastReceiver的应用 6.2 手机电池计量还剩多少——使用BroadcastReceiver捕捉Intent.ACTION_BATTERY_CHANGED 6.3 群发拜年短信给联系人——ACTION_PICK与Uri对象 6.4 开始与停止系统服务——Service与Runnable整合并用 6.5 通过短信发送email通知——BroadcastReceiver与Intent整合 6.6 手机拨接状态——PhoneStateListener之onCallStateChanged 6.7 有来电,发送邮件通知——PhoneStateListener与ACTION_SEND 6.8 存储卡剩余多少容量——Environment加StatFs 6.9 访问本机内存与存储卡——File的创建与删除 6.10 实现可定时响起的闹钟——PendingIntent与AlarmManager的运用 6.11 黑名单来电自动静音——PhoneStateListener与AudioManager 6.12 手机翻背面即静音震动——SensorListener及AudioManager整合应用 6.13 指定时间置换桌面背景——多AlarmManager事件处理 6.14 判断发送短信后的状态——BroadcastReceiver聆听PendingIntent 6.15 后台服务送出广播信息——sendBroadcast与BroadcastReceiver 6.16 开机程序设计——receiver与intent-filter协同作业 6.17 双向短信常驻服务——Service与receiver实例 第7章 娱乐多媒体 7.1 访问Drawable资源的宽高——ContextMenu与Bitmap的应用 7.2 绘制几何图形——使用android.graphics类 7.3 手机屏幕保护程序——FadeIn/FadeOut特效与运行线程 7.4 用手指移动画面里的照片——onTouchEvent事件判断 7.5 加载存储卡的Gallery相簿——FileArrayList 7.6 取得手机内置媒体里的图文件——ACTION_GET_CONTENT取回InputStream 7.7 相片导航向导与设置背景桌面——ImageSwitcher与Gallery 7.8 调整音量大小声——AudioManager控制音量 7.9 播放mp3资源文件——raw文件夹与MediaPlayer的使用 7.10 播放存储卡里的mp3音乐——MediaPlayer.setDataSource 7.11 自制录音/播放录音程序——MediaRecorder与AudioEncoder 7.12 通过收到短信开始秘密录音——MediaRecorder与BroadcastReceiver实例 7.13 内置影片播放器载入3gp电影——VideoViewWidget 7.14 自制3gp影片播放器——MediaPlayer与实现SurfaceView 7.15 相机预览及拍照临时文件——Camera及PictureCallback事件 第8章 当Android与Internet接轨 8.1 HTTPGET/POST传递参数——HTTP连接示范 8.2 在程序里浏览网页——WebView.loadUrl 8.3 嵌入HTML标记的程序——WebView.loadData 8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery中显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——HttpURLConnection与URLConnection和运行线程 8.8 通过网络播放MP3——Runnable存储FileOutputStream技巧 8.9 设置远程下载音乐为手机铃声——RingtoneManager与铃声存放路径 8.10 远程下载桌面背景图案——URLConnection与setWallpaper()搭配 8.11 将手机文件上传至网站服务器——模拟HTTPFORM的POSTACTION 8.12 移动博客发布器——以XML-RPC达成远程过程调用 8.13 移动RSS阅读器——利用SAXParser解析XML 8.14 远程下载安装Android程序——APKInstaller的应用 8.15 手机下载看3gp影片——Runnable混搭SurfaceView 8.16 访问网站LoginAPI——远程服务器验证程序运行权限 8.17 地震速报!——HttpURLConnection与Service侦测服务 第9章 Google服务与Android混搭 9.1 Google帐号验证Token——AuthSub 9.2 Google搜索——AutoCompleteTextView与GoogleSearchAPI 9.3 前端产生QRCode二维条形码——GoogleChartAPI 9.4 以经纬度查找目的地位置——GeoPoint与MapView的搭配运用 9.5 GPSGoogle地图——LocationListener与MapView实时更新 9.6 移动版GoogleMap——Geocoder反查Address对象 9.7 规划导航路径——DirectionsRoute 9.8 移动设备上的Picasa相册——GooglePicasaAPI 9.9 随身翻译机——GoogleTranslateAPI 第10章 创意Android程序设计 10.1 手机手电筒——PowerManager控制WakeLock并改变手机亮度 10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode二维条形码扫描仪——BitmapFactory.decodeByteArray 10.6 上班族今天中午要吃什么——热量骰子地图 10.7 掷杯筊——把手机放在空中甩事件处理...

113

社区成员

发帖
与我相关
我的任务
社区描述
微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。
windowsmicrosoft 个人社区
社区管理员
  • 微软技术分享
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。

试试用AI创作助手写篇文章吧