.386
.model flat,stdcall
option casemap:none
include windows.inc
include masm32.inc
include kernel32.inc
include user32.inc
includelib masm32.lib
includelib kernel32.lib
includelib user32.lib
.data?
CharOut db 100 dup(?)
.code
OutEdxEax PROTO :DWORD
OutEdxEax proc lpString ;定义OutEdxEax子函数
mov edi,lpString ;指向存放结果的地址
mov esi,lpString
mov eax,123H ;测试0x100000123的10进制大小
mov edx,1
mov ecx,10 ;转换成十进制
.while eax!=0 || edx!=0
push eax ;eax压栈
mov eax,edx ;eax=edx
xor edx,edx ;edx=0
div ecx ;/10,eax存商,余数存edx
mov ebx,eax ;ebx存商
pop eax ;恢复eax
div ecx ;/10,eax存商,余数存edx
add dl,'0' ;dl增加'0',edx变成字符串
mov [edi],dl ;存放结果
inc edi
mov edx,ebx ;商存入edx
.endw
mov BYTE ptr [edi],0;字符串以0为结尾
dec edi
.while edi>esi ;结果前变后,后变前!
mov al,[esi]
xchg al,[edi]
mov [esi],al
inc esi
dec edi
.endw
ret
OutEdxEax endp
start: ;程序开始
xor eax,eax ;存放结果的寄存器EDX:EAX=1
xor edx,edx
inc eax
mov ecx,20 ;计算20的阶乘。不能大于20,否则会溢出,结果将不再正确!
.while ecx>0
.if edx==0 ;结果在EAX中
mul ecx
.else ;结果在EDX:EAX中
push edx
mul ecx
pop ebx
push eax
push edx
mov eax,ecx
mul ebx
pop edx
add edx,eax
pop eax
.endif
dec ecx
.endw
.if edx==0 ;结果在EAX中
invoke dw2a,eax,addr CharOut
.else ;结果在EDX:EAX中
invoke OutEdxEax,addr CharOut ;用我们自己的程序转换!
.endif
invoke StdOut,addr CharOut ;控制台输出结果
invoke ExitProcess,NULL ;结束程序
end start
结果:
F:\MASM>ml /c /coff 3.asm
Microsoft (R) Macro Assembler Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: 3.asm
***********
ASCII build
***********
F:\MASM>link /subsystem:console 3.obj
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
F:\MASM>3.exe
4294967587
即0x100000123 = 4294967587
MUL:
操作数大小 | 源操作数 1 | 源操作数 2 | 目标操作数 |
字节 | AL | r/m8 | AX |
字 | AX | r/m16 | DX:AX |
双字 | EAX | r/m32 | EDX:EAX |
如果参数是 r16/m16, 把AX做乘数, 结果放在EAX
如果参数是 r32/m32, 把EAX做乘数, 结果放在EDX:EAX
结果存储到寄存器 AX、寄存器对 DX:AX 或 EDX:EAX(取决于操作数大小),乘积的高位分别保存在寄存器 AH、DX 或 EDX。如果乘积的高位均为 0,则清除 CF 与 OF 标志;否则将它们设置为 1。
DIV:
将 AX 寄存器、DX:AX 寄存器对或 EDX:EAX 寄存器对中的值(被除数)除以(无符号)源操作数(除数),结果存储到 AX (AH:AL)、DX:AX 或 EDX:EAX 寄存器。源操作数可以是通用寄存器或内存位置。此指令的操作取决于操作数大小,具体如下表所示:
操作数大小 | 被除数 | 除数 | 商 | 余数 | 商的最大值 |
字/字节 | AX | r/m8 | AL | AH | 255 |
双字/字 | DX:AX | r/m16 | AX | DX | 65,535 |
四字/双字 | EDX:EAX | r/m32 | EAX | EDX | 232 - 1 |
如果参数是r8/m8,把AX做被除数;商->AL,余数->AH
如果参数是r16/m16,把DX:AX做被除数;商->AX,余数->DX
如果参数是r32/m32,把EDX:EAX做被除数;商->EAX,余数->EDX
XCHG:
操作码 | 指令 | 说明 |
90+rw | XCHG AX,16 | 交换 r16 与 AX |
90+rw | XCHG r16, X | 交换 AX 与 r16 |
90+rd | XCHG EAX, r32 | 交换 r32 与 EAX |
90+rd | XCHG r32, EAX | 交换 EAX 与 r32 |
86 /r | XCHG r/m8, r8 | 交换 r8(字节寄存器)与 r/m8 中的字节 |
86 /r | XCHG r8, r/m8 | 交换 r/m8 中的字节与 r8(字节寄存器) |
87 /r | XCHG r/m16, r16 | 交换 r16 与 r/m16 中的字 |
87 /r | XCHG r16, r/m16 | 交换 r/m16 中的字与 r16 |
87 /r | XCHG r/m32, r32 | 交换 r32 与 r/m32 中的双字 |
87 /r | XCHG r32, r/m32 | 交换 r/m32 中的双字与 r32 |
交换目标(第一个)操作数与源(第二个)操作数的内容。操作数可以是两个通用寄存器,也可以是寄存器与内存位置