彙編語言計算2^12保存在AX寄存器,並以十進制形式輸出(16位和32位)

win1、計算2^12保存在AX中(王爽彙編語言第二版p100):算法

mov  	cx,12		;循環12次
		mov     ax,1		;初始化AX
s:		add		ax,ax
		loop  	s			;執行完loop後,要顯示的數字2^12 已經在寄存器AX

2、AX寄存器以顯示說明:windows

本例中,2^12=4096,故AX=1000Happ

則輸出字符爲4096工具

原理:
ax爲十六位寄存器,因此輸出十進制數範圍爲0 - 65535,最大五位數,故設置CX=5,LOOP語句實現算法:
4096/10000= 商0  餘數4096    ; 根據十進制書寫習慣,不輸出前面的0字符 ,須要在輸出循環裏判斷
4096/1000= 商4  餘數96         ;輸出4
96/100= 商0  餘數96              ;輸出0
96/10=  商9  餘數6                 ;輸出9
6/1=  商6  餘數0                     ;輸出6
把每次所得商加上48便可獲得相應數字的ASCII碼,oop

3、完整代碼:測試

code segment
assume cs:code,ds:data,ss:stack
start:
        mov     ax,data
        mov     ds,ax
		
	mov  	cx,12		;循環12次
	mov     ax,1		;初始化AX
s:	add		ax,ax
	loop  	s			;執行完loop後,要顯示的數字2^12 已經在寄存器AX

        mov     si, offset divisors
        mov     di, offset results                     
        mov     cx,5   
aa:
        mov     dx,0            
        div     word ptr [si]   ;除法指令的被除數是隱含操做數,此處爲dx:ax,商ax,餘數dx
        add     al,48           ;商加上48便可獲得相應數字的ASCII碼
        mov     byte ptr [di],al        
        inc     di                                
        add     si,2                           
        mov     ax,dx                        
        loop    aa
        mov     cx,4    
        mov     di, offset results 
bb:
        cmp     byte ptr [di],'0'   ;不輸出前面的0字符    
        jne     print
        inc     di                           
        loop    bb
print:
        mov     dx,di                       
        mov     ah,9
        int     21h                   
        mov     ax,4C00h       
        int     21h
code ends
data    segment
divisors        DW 10000, 1000, 100, 10, 1
results          DB 0,0,0,0,0,"$"        ;存放五位數ASCII碼
data ends
stack segment STACK
stack ends
end start

4、DOSBOX運行截圖(dosbox已安裝masm611,並真確設置環境變量)ui

5、win32彙編(在win10 64位下可執行)spa

須要下載masm32,解壓到d:根目錄下:.net

設置環境:var.bat3d

@echo off
set include=D:\masm32\include
set lib=D:\masm32\lib
set path=D:\masm32\bin;%path%
echo on

計算2^12的win32彙編代碼:

.386
.model flat, stdcall

include \masm32\include\msvcrt.inc
includelib \masm32\lib\msvcrt.lib

.data
    szFmt db '2^12=%d;', 0

.code
start:
	mov 	eax, 0
	mov     ax,1		;初始化AX

	mov 	ecx, 0		;初始化循環次數,設爲12次
	mov  	cx,12

s:
	add		ax,ax
	loop  	s			;執行完loop後,要顯示的數字2^12 已經在寄存器AX

    invoke crt_printf, addr szFmt, eax
    ret
end start

彙編,並運行:

D:\masm32\MyPrg>type var.bat
@echo off
set include=D:\masm32\include
set lib=D:\masm32\lib
set path=D:\masm32\bin;%path%
echo on
D:\masm32\MyPrg>var

D:\masm32\MyPrg>ml /coff 5_1.asm /link /subsystem:console
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

 Assembling: 5_1.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console
"5_1.obj"
"/OUT:5_1.exe"

D:\masm32\MyPrg>5_1.exe
2^12=4096;

MASM32 控制檯輸入口令:

代碼mypass.asm

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
;MASM32 控制檯輸入口令
; 使用如下列命令進行編譯和連接:
;ml /coff  mypass.asm /link /subsystem:console
.386
.model flat, stdcall
option casemap : none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include masm32.inc
includelib masm32.lib
include user32.inc
includelib user32.lib
include msvcrt.inc
includelib msvcrt.lib  

.data
	Password BYTE '1234567', 0
	PasswordLength BYTE $ - Password
	Welcome BYTE 'Please input password', 0Ah, 0Dh, 0
	format  BYTE '%s', 0
	OK		BYTE 'OK!', 0
	WRONG   BYTE 'NO!', 0

.code
main PROC
	
	local @valid_flag : dword
	local @buffer[1024] : byte
	local @authenticated : dword 
	local @small_buffer[8] : byte

	mov @valid_flag, 0

	.while 1
		push OFFSET Welcome
		call crt_printf
		add  esp, 4

		lea  eax, @buffer
		push eax
		push OFFSET format
		call crt_scanf
	    add  esp, 8

	    jmp check

	begin:
		.if eax == 0
			push OFFSET OK
			call crt_printf
			add  esp, 4
			jmp  exit
		.else 
			push OFFSET WRONG
			call crt_printf
			add  esp, 4
		.endif
	.endw

	check:

		lea   eax, @buffer
		push  eax
		push  OFFSET Password
		call  crt_strcmp
		add   esp, 8
		jmp   begin


  	exit:
		invoke ExitProcess, 0

main ENDP
END main

運行:

D:\masm32\MyPrg>var

D:\masm32\MyPrg>ml /coff  mypass.asm /link /subsystem:console
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

 Assembling: mypass.asm

***********
ASCII build
***********

Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console
"mypass.obj"
"/OUT:mypass.exe"

D:\masm32\MyPrg>mypass.exe
Please input password
1234567
OK!
D:\masm32\MyPrg>

win32彙編一個建立窗口的程序:

;編譯命令
; ml /coff Mywin.asm /link /subsystem:windows 

                .386
                .model flat, stdcall
                option casemap :none   ; case sensitive
 
include         windows.inc
include         user32.inc
include         kernel32.inc
include         comctl32.inc
include         comdlg32.inc
include         gdi32.inc
 
includelib      user32.lib
includelib      kernel32.lib
includelib      comctl32.lib
includelib      comdlg32.lib
includelib      gdi32.lib
 
IDI_MAIN        equ             1000            ;icon
 
IDM_MAIN        equ             4000            ;menu
IDM_EXIT        equ             4001
 
                .data?
 
hInstance       dd              ?
hWinMain        dd              ?
hMenu           dd              ?
hIcon           dd              ?
szBuffer        db      256 dup (?)
 
                .data
 
szClassName     db      "Windows Template",0
szCaptionMain   db      '窗口模板',0
 
                .code
 
start:
                call    _WinMain
                invoke  ExitProcess,NULL
 
_WinMain        proc
                local   @stWcMain:WNDCLASSEX
                local   @stMsg:MSG
 
                invoke  InitCommonControls
                invoke  GetModuleHandle,NULL
                mov     hInstance,eax
                invoke  LoadIcon,hInstance,IDI_MAIN
                mov     hIcon,eax
                invoke  LoadMenu,hInstance,IDM_MAIN
                mov     hMenu,eax
;*************** 註冊窗口類 *****************************************
                invoke  LoadCursor,0,IDC_ARROW
                mov     @stWcMain.hCursor,eax
                mov     @stWcMain.cbSize,sizeof WNDCLASSEX
                mov     @stWcMain.hIconSm,0
                mov     @stWcMain.style,CS_HREDRAW or CS_VREDRAW
                mov     @stWcMain.lpfnWndProc,offset WndMainProc
                mov     @stWcMain.cbClsExtra,0
                mov     @stWcMain.cbWndExtra,0
                mov     eax,hInstance
                mov     @stWcMain.hInstance,eax
                mov     @stWcMain.hIcon,0
                mov     @stWcMain.hbrBackground,COLOR_WINDOW + 1
                mov     @stWcMain.lpszClassName,offset szClassName
                mov     @stWcMain.lpszMenuName,0
                invoke  RegisterClassEx,addr @stWcMain
;*************** 創建輸出窗口 ***************************************
                invoke  CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain, WS_OVERLAPPEDWINDOW OR WS_VSCROLL OR WS_HSCROLL,0,0,550,300,NULL,hMenu,hInstance,NULL
 
                invoke  ShowWindow,hWinMain,SW_SHOWNORMAL
                invoke  UpdateWindow,hWinMain
;*************** 消息循環 *******************************************
                .while  TRUE
                        invoke  GetMessage,addr @stMsg,NULL,0,0
                        .break  .if eax == 0
                        invoke  TranslateMessage,addr @stMsg
                        invoke  DispatchMessage,addr @stMsg
                .endw
                ret
 
_WinMain        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndMainProc     proc    uses ebx edi esi,hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
 
                mov     eax,uMsg
                .if     eax ==  WM_CREATE
                        mov     eax,hWnd
                        mov     hWinMain,eax
                        call    _Init
;********************************************************************
                .elseif eax ==  WM_COMMAND
                   .if  lParam == 0
                        mov     eax,wParam
                        .if     ax == IDM_EXIT
                                call    _Quit
                        .endif
                   .endif
;********************************************************************
                .elseif eax ==  WM_CLOSE
                        call    _Quit
;********************************************************************
                .else
                        invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
                        ret
                .endif
                xor     eax,eax
                ret
 
WndMainProc     endp
 
_Init           proc
 
                invoke  SendMessage,hWinMain,WM_SETICON,ICON_SMALL,hIcon
 
                ret
 
_Init           endp
;********************************************************************
_Quit           proc
 
                invoke  DestroyWindow,hWinMain
                invoke  PostQuitMessage,NULL
                ret
 
_Quit           endp
;********************************************************************
                end     start

win32彙編求fibonacci數列:

;  ml /coff fibonacci.asm /link /subsystem:console
;  原文:https://blog.csdn.net/codes_first/article/details/78279641 

.486
.model flat, stdcall

option casemap:none

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\masm32.lib


include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc
include \masm32\include\windows.inc
include \masm32\include\msvcrt.inc
include \masm32\include\masm32.inc
include \masm32\macros\macros.asm

.data
    n dd 0
    a dd 0
    b dd 1
    i dd 1
    t dd 0
.code
start:
    mov eax, sval(input("Enter a number : "))
    mov n,eax
    print chr$("Fibonacci_number")
    print str$(1)
    print chr$(" is ")
    print str$(b)
    print chr$(" ",13,10)
    mov ecx,n
    mov i,ecx
    dec i
    .while i
        mov eax,b
        mov t,eax
        mov eax,b
        add eax,a
        mov b,eax
        print chr$("Fibonacci_number")
        mov ecx,n
        sub ecx,i
        inc ecx
        print str$(ecx)
        print chr$(" is ")
        print str$(b)
        print chr$(" ",13,10)
        mov eax,t
        mov a,eax
        dec i
    .endw
    ret
end start

6、win64彙編(UASM本身打包:包含vs21017的ml64,link;jwasm,jwlink;uasm;環境設置腳本

解壓uasm64如:d:\uasm64

進入工做目錄運行環境設置腳本var64.bat:

@echo off
set include=D:\UASM64\include
set lib=D:\UASM64\lib
set path=D:\UASM64\bin;%path%
echo on

測試代碼Win64_1.asm:

extrn MessageBoxA: proc

.data
	text     db 'Hello x64!', 0
	caption  db 'My First x64 Application', 0

.code
main proc
	sub rsp,28h
	xor r9d,r9d
	lea r8, caption
	lea rdx, text
	xor rcx,rcx
	call MessageBoxA
	add rsp,28h
	ret

main ENDP
end

打開VS2017的X64本機工具命令:

 

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>d:

D:\>cd prg\Win32Asm

D:\prg\Win32Asm>ml64 Win64_1.asm /link /subsystem:windows /entry:main  user32.lib
Microsoft (R) Macro Assembler (x64) Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: Win64_1.asm
Microsoft (R) Incremental Linker Version 14.16.27031.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/OUT:Win64_1.exe
Win64_1.obj
/subsystem:windows
/entry:main
user32.lib

D:\prg\Win32Asm>

測試代碼Win64_2.asm:

option casemap:none

HINSTANCE typedef QWORD
HWND      typedef QWORD
HMENU     typedef QWORD
HICON     typedef QWORD
HBRUSH    typedef QWORD
HCURSOR   typedef QWORD
WPARAM    typedef QWORD
LPARAM    typedef QWORD
LPSTR     typedef QWORD
LPVOID    typedef QWORD
UINT      typedef DWORD

NULL           equ 0
WS_OVERLAPPEDWINDOW equ 0CF0000h
CW_USEDEFAULT  equ 80000000h
SW_SHOWDEFAULT equ 10
SW_SHOWNORMAL  equ 1
IDC_ARROW      equ 32512
IDI_APPLICATION equ 32512
WM_DESTROY     equ 2
CS_VREDRAW     equ 1
CS_HREDRAW     equ 2
COLOR_WINDOW   equ 5

proto_WNDPROC typedef proto :HWND,:UINT,:WPARAM,:LPARAM
WNDPROC typedef ptr proto_WNDPROC

WNDCLASSEXA struct 8
cbSize          DWORD   ?
style           DWORD   ?
lpfnWndProc     WNDPROC ?
cbClsExtra      DWORD   ?
cbWndExtra      DWORD   ?
hInstance       HINSTANCE ?
hIcon           HICON   ?
hCursor         HCURSOR ?
hbrBackground   HBRUSH  ?
lpszMenuName    LPSTR   ?
lpszClassName   LPSTR   ?
hIconSm         HICON   ?
WNDCLASSEXA ends

POINT   struct
x   SDWORD  ?
y   SDWORD  ?
POINT   ends

MSG struct 8
hwnd    HWND    ?
message DWORD   ?
wParam  WPARAM  ?
lParam  LPARAM  ?
time    DWORD   ?
pt      POINT   <>
MSG ends

GetModuleHandleA proto :LPSTR
GetCommandLineA  proto
ExitProcess      proto :UINT
LoadIconA        proto :HINSTANCE, :LPSTR
LoadCursorA      proto :HINSTANCE, :LPSTR
RegisterClassExA proto :ptr WNDCLASSEXA
CreateWindowExA  proto :DWORD, :LPSTR, :LPSTR, :DWORD, :SDWORD, :SDWORD, :SDWORD, :SDWORD, :HWND, :HMENU, :HINSTANCE, :LPVOID
ShowWindow       proto :HWND, :SDWORD
UpdateWindow     proto :HWND
GetMessageA      proto :ptr MSG, :HWND, :SDWORD, :SDWORD
TranslateMessage proto :ptr MSG
DispatchMessageA proto :ptr MSG
PostQuitMessage  proto :SDWORD
DefWindowProcA   proto :HWND, :UINT, :WPARAM, :LPARAM

WinMain proto :HINSTANCE, :HINSTANCE, :LPSTR, :UINT

    .data

ClassName db "SimpleWinClass",0
AppName  db "Our First Window",0

    .data?

hInstance HINSTANCE ?
CommandLine LPSTR ?

    .code

start:
    and    rsp, -16
    invoke GetModuleHandleA, NULL
    mov    hInstance, rax
    invoke GetCommandLineA
    mov    CommandLine, rax
    invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess, eax

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:UINT

    LOCAL wc:WNDCLASSEXA
    LOCAL msg:MSG
    LOCAL hwnd:HWND

    and   rsp, -16        ;to make the stack 16byte aligned

    mov   hInst, rcx      ;hInst is the name of the shadow space variable!

    mov   wc.cbSize, SIZEOF WNDCLASSEXA
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
;   mov   rax, OFFSET WndProc  ;using LEA is preferable
    lea   rax, [WndProc]
    mov   wc.lpfnWndProc, rax
    mov   wc.cbClsExtra, NULL
    mov   wc.cbWndExtra, NULL
    mov   wc.hInstance, rcx
    mov   wc.hbrBackground, COLOR_WINDOW+1
    mov   wc.lpszMenuName, NULL
;    mov   rax, OFFSET ClassName  ;using LEA is preferable
    lea   rax, [ClassName]
    mov   wc.lpszClassName, rax
    invoke LoadIconA, NULL, IDI_APPLICATION
    mov   wc.hIcon, rax
    mov   wc.hIconSm, rax
    invoke LoadCursorA, NULL, IDC_ARROW
    mov   wc.hCursor,rax
    invoke RegisterClassExA, addr wc
    invoke CreateWindowExA, NULL, ADDR ClassName, ADDR AppName,\
           WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,\
           CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL, NULL,\
           hInst, NULL
    mov   hwnd,rax
    invoke ShowWindow, hwnd, SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    .while (1)
        invoke GetMessageA, ADDR msg, NULL, 0, 0
        .break .if (!rax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessageA, ADDR msg
    .endw
    mov   rax, msg.wParam
    ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    and rsp,-16
    .if ( edx == WM_DESTROY )
        invoke PostQuitMessage, NULL
    .else
        invoke DefWindowProcA, rcx, edx, r8, r9
        ret
    .endif
    xor rax,rax
    ret
WndProc endp

end start

編譯:

D:\prg\Win32Asm>var64

D:\prg\Win32Asm>jwasm -win64 Win64_2.asm
JWasm v2.11, Oct 20 2013, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

Win64_2.asm: 178 lines, 3 passes, 0 ms, 0 warnings, 0 errors

D:\prg\Win32Asm>jwlink format win pe ru win file Win64_2.obj lib kernel32.lib, user32.lib
JWlink Version 1.9beta 13
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
loading object files
searching libraries
creating a 64-bit PE executable

D:\prg\Win32Asm>win64_2.exe

win64的console程序例子:

;環境設置  var64.bat
;---   jwasm.exe -c -win64 -Zp8 -nologo  Win64Hello1.asm
;---   jwlink.exe f Win64Hello1.obj lib {kernel32.lib user32.lib}
        
;--- the simplest Win64 hello world console application.

	option casemap:none

	.nolist
	.nocref
WIN32_LEAN_AND_MEAN equ 1
	include windows.inc
	.list
	.cref

;--- CStr(): macro function to simplify defining a string

CStr macro pszText:VARARG
local szText
	.const
szText	db pszText,0
	.code
	exitm <offset szText>
endm

	.CODE

main proc c uses rbx rsi rdi

	invoke GetStdHandle,STD_OUTPUT_HANDLE
	mov rbx,rax
	mov rsi, CStr("Hello, world",13,10)
	invoke lstrlen, rsi
	push 0
	mov rdi, rsp
	invoke WriteConsoleA, rbx, rsi, eax, rdi, 0
	pop rax
	ret

main endp

mainCRTStartup proc
	and rsp,-16
	call main
	invoke ExitProcess, eax
mainCRTStartup endp

	END mainCRTStartup

編譯運行:

D:\prg\Win32Asm>var64

D:\prg\Win32Asm>jwasm.exe -c -win64 -Zp8 -nologo  Win64Hello1.asm
Win64Hello1.asm: 48 lines, 2 passes, 31 ms, 0 warnings, 0 errors

D:\prg\Win32Asm>jwlink.exe f Win64Hello1.obj lib {kernel32.lib user32.lib}
JWlink Version 1.9beta 13
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
loading object files
searching libraries
creating a 64-bit PE executable

D:\prg\Win32Asm>Win64Hello1.exe
Hello, world
相關文章
相關標籤/搜索