win一、计算2^12保存在AX中(王爽汇编语言第二版p100):
mov cx,12 ;循环12次
mov ax,1 ;初始化AX
s: add ax,ax
loop s ;执行完loop后,要显示的数字2^12 已经在寄存器AX
二、AX寄存器以显示说明:
本例中,2^12=4096,故AX=1000H
则输出字符为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码,
三、完整代码:
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
四、DOSBOX运行截图(dosbox已安装masm611,并真确设置环境变量)
五、win32汇编(在win10 64位下可执行)
需要下载masm32,解压到d:根目录下:
设置环境:var.bat
@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
六、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
%comspec% /k "D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_x64 %*
测试代码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
编译运行:
var64.bat
@echo off
set include=D:\UASM64\include
set lib=D:\UASM64\lib
set path=D:\UASM64\bin;%path%
echo on
%comspec% /k "D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_x64 %*
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
用nasm来汇编win32和win64位程序:
代码:
; nasm -f win32 hello1win32.asm
; var
; link /subsystem:console /nodefaultlib /entry:main hello1win32.obj kernel32.lib
STD_OUTPUT_HANDLE equ -11
NULL equ 0
global _main
extern _ExitProcess@4, _GetStdHandle@4, _WriteConsoleA@20
section .data
msg db "Hello World!", 13, 10, 0
msg.len equ $ - msg
section .bss
dummy resd 1
section .text
_main:
push STD_OUTPUT_HANDLE
call _GetStdHandle@4
push NULL
push dummy
push msg.len
push msg
push eax
call _WriteConsoleA@20
push NULL
call _ExitProcess@4
汇编和运行:
D:\prg\mynasm>nasm -f win32 hello1win32.asm
D:\prg\mynasm>var
D:\prg\mynasm>link /subsystem:console /nodefaultlib /entry:main hello1win32.obj kernel32.lib
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
D:\prg\mynasm>hello1win32.exe
Hello World!
需要说明的是连接器还是用ms的link故还需用var.bat设置环境。
64位:
代码:hello1win64.asm
; nasm -f win64 hello1win64.asm
; var64
; link /subsystem:console /nodefaultlib /entry:main /machine:X64 hello1win64.obj kernel32.lib
STD_OUTPUT_HANDLE equ -11
NULL equ 0
global main
extern ExitProcess, GetStdHandle, WriteConsoleA
section .data
msg db "Hello World!", 13, 10, 0
msg.len equ $ - msg
section .bss
dummy resq 1
section .text
main:
mov ecx,0fffffff5h
call GetStdHandle
mov r9,dummy
mov r8d,0dh
mov rdx,msg
mov rcx,rax
call WriteConsoleA
push NULL
call ExitProcess
汇编和运行:
D:\prg\mynasm>var64.bat
D:\prg\mynasm>C:\Windows\system32\cmd.exe /k "D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x86_x64
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.4.5
** Copyright (c) 2019 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x86_x64'
D:\prg\mynasm>nasm -f win64 hello1win64.asm
D:\prg\mynasm>link /subsystem:console /nodefaultlib /entry:main /machine:X64 hello1win64.obj kernel32.lib
Microsoft (R) Incremental Linker Version 14.24.28316.0
Copyright (C) Microsoft Corporation. All rights reserved.
D:\prg\mynasm>hello1win64.exe
Hello World!
来源:oschina
链接:https://my.oschina.net/u/2245781/blog/3062540