汇编实现 hello world

1.利用RadASM 写汇编程序

    本文介绍利用RedASM写一个messageBox “hello world”.

 .386
 .model flat, stdcall
 option casemap :none
  
 include windows.inc
 include kernel32.inc
 include masm32.inc 
 includelib kernel32.lib
 includelib masm32.lib
 
 .data
     helloWorld db "hello world",0
     
 .code
     start:
         invoke StdOut, addr helloWorld
         invoke ExitProcess,0
     
     end start

2.习题:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 
写成c代码很简单: 

void p1_fun()

{

    for (int i = 1; i <= 4; ++i){

        for (int j = 1; j <= 4; ++j){

            for (int k = 1; k <=4; ++k){

                if (i !=j && i !=k && j != k){

                    ostringstream stringStream;

                    stringStream<<i<<j<<k;

                    cout<<stringStream.str()<<",";

                }

            }

        }

    }

}

  用汇编实现如下

Title: Hello world

 ;Author: sld6666666@gmail.com   

 ;Data: 2012-11-29

 ;Description: Assemble hello world

 .386                ;¸Ã³ÌÐò¶ÔCPUµÄ×îµÍÒªÇóÊÇintel 386

 .model flat, stdcall        ; ƽ̹ÄÚ´æÄ£ÐÍ£¬ stacll º¯Êýµ÷Ó÷½Ê½

 .stack 4096            ;Õ»µÄ´óСΪ4096B

 option casemap:none

  

 ;include Í·Îļþ£¬ Á¬½Ó¿â

include msvcrt.inc

includelib msvcrt.lib

  

 .data                    ;Êý¾Ý¶Î

     index_0 dd  dword

     index_1 dd  dword

     index_2 dd  dword

     szFmt db '%d%d%d', 0

     entryFmt db '  ',0

  

 .code

     start:

        mov index_0, 0

      

        forProcess_0:

            cmp index_0, 5

            jge rtnProcess 

            inc index_0

            mov index_1, 0

             

            forProcess_1:

                cmp index_1, 5

                jge forProcess_0

                inc index_1

                mov index_2, 0

                 

                forProcess_2:

                    cmp index_2, 5

                    jge forProcess_1

                    inc index_2

                     

                    mov eax, index_0

                    mov ebx, index_1

                    mov edx, index_2

                     

                    cmp eax, ebx

                    je forProcess_2

                     

                    cmp eax, edx

                    je forProcess_2

                     

                    cmp ebx, edx

                    je forProcess_2

                     

                    invoke crt_printf, addr szFmt,eax, ebx, edx

                    invoke crt_printf, addr entryFmt

                    jmp forProcess_2

        rtnProcess:

            ret

      

     end start

  解释下几个关键点: 
1. 输出函数利用了 msvcrt 中的printf 
2. 导入库的关键字为includelib, 头文件的关键字为 include, 如include msvcrt.inc,includelib msvcrt.lib 
3. 使用导入函数的关键字为 invoke

3习题: 输入某年某月某日,判断这一天是这一年的第几天?

c++代码如下, 算法不太严谨,主要为了反汇编的练习也不讲究了

void doFun(int year, int month, int day){

    int days =  month*30+day;

    days += month/2 + month%2;//31天的月

    if (month >= 2){

        days -= (year%4==0)?1:2;

    }

    cout << days <<endl;

}

 

相应的汇编代码为:

Title: Hello world

 ;Author: sld6666666@gmail.com   

 ;Data: 2012-11-29

 ;Description: Assemble hello world

 .386               

 .model flat, stdcall   

 .stack 4096           

 option casemap:none

  

include msvcrt.inc

includelib msvcrt.lib

  

 .data                   

    year dword  2009

    month dword 5

    day dword 24

    totalDays dword 0

     

    szFmt db '%d', 0

  

 .code

     start:

         

        ;int days =  month*30+day;

        mov eax, 30

        mul month

        add eax, day

        mov totalDays, eax

         

        ;days += month/2 + month%2;//31ÌìµÄÔÂ

        mov eax, month

        cdq

        mov ebx, 2

        idiv ebx

        add totalDays, ebx

        add totalDays, edx

         

  

        ;if (month >= 2){

        ;   days -= (year%4==0)?1:2;

        ;}

         

        mov  eax, month

        cmp eax, 2

        jb printProcess

         

        mov eax, year

        cdq

        mov ebx, 4

        idiv ebx

        cmp edx, 0

        je L1

        sub totalDays, 2

        jmp printProcess

            L1:

            sub totalDays, 1

         

        printProcess:

            invoke crt_printf, addr szFmt,totalDays

         

        rtnProcess:

            ret

      

     end start

汇编练习题(3)

题目:输入三个整数x,y,z,请把这三个数由小到大输出

c++ 代码很简单

void doFunP3(int x, int y, int z){

    if (x > y)swap(x, y);

    if (x > z)swap(x, z);

    if (y > z) swap(y, z);

    cout<< x <<','<< y <<','<< z <<endl;

}

汇编的代码如下

     

 .data                    ;Êý¾Ý¶Î                 
    x dword 200
    y dword 10
    z dword 400
    printFmt db '%d,%d,%d', 0
    
.code
    sortEaxEbx proc 
        cmp eax, ebx
        jbe rtnProcess
    
        swapProcess:
            xchg eax, ebx
    
        rtnProcess:
            ret

    sortEaxEbx endp

     print proc 
        mov eax, x
        mov ebx, y
        invoke  sortEaxEbx 
        mov x, eax
        mov y, ebx
        
        mov eax, x
        mov ebx, z
        invoke sortEaxEbx
        mov x, eax
        mov z, ebx
        
        mov eax, y
        mov ebx, z
        invoke sortEaxEbx
        mov y, eax
        mov z, ebx
        
        invoke crt_printf, addr printFmt, x, y, z
        ret
        
    print endp
    

这里说下几个注意的点:

1. invoke 伪指令等同于call指令,但是比call 更强大

2. 如果要在不同的文件中实现模块功能, 一定要遵循如下:

  a)建立一个头文件,如: p3.inc, 并在此头文件中声明函数:  print PROTO

  b) 在相应的实现文件中实现功能代码, p3.asm:    

print proc

re

print endp

  c): 作为调用者main.cpp 必须包含头文件和实现文件

include p3.inc
include p3.asm

    d). 如果 功能函数不被导出, 则不必在头文件中声明

    e):不管是什么样的实现函数必须放在.code中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值