WEB开发网      婵犵數濮烽弫鍛婄箾閳ь剚绻涙担鍐叉搐绾剧懓鈹戦悩瀹犲闁汇倗鍋撻妵鍕箛閸洘顎嶉梺绋款儑閸犳劙濡甸崟顖氬唨闁靛ě浣插亾閹烘鈷掗柛鏇ㄥ亜椤忣參鏌″畝瀣暠閾伙絽銆掑鐓庣仭缁楁垿姊绘担绛嬪殭婵﹫绠撻、姘愁樄婵犫偓娴g硶鏀介柣妯款嚋瀹搞儱螖閻樺弶鍟炵紒鍌氱Ч瀹曟粏顦寸痪鎯с偢瀵爼宕煎☉妯侯瀳缂備焦顨嗗畝鎼佸蓟閻旈鏆嬮柣妤€鐗嗗▓妤呮⒑鐠団€虫灀闁哄懐濮撮悾鐤亹閹烘繃鏅濋梺闈涚墕濡瑩顢欒箛鏃傜瘈闁汇垽娼ф禒锕傛煕閵娿儳鍩f鐐村姍楠炴﹢顢欓懖鈺嬬幢闂備浇顫夊畷妯肩矓椤旇¥浜归柟鐑樻尭娴滃綊姊虹紒妯虹仸闁挎洍鏅涜灋闁告洦鍨遍埛鎴︽煙閼测晛浠滃┑鈥炽偢閹鈽夐幒鎾寸彇缂備緡鍠栭鍛搭敇閸忕厧绶炴俊顖滅帛濞呭洭姊绘担鐟邦嚋缂佽鍊垮缁樼節閸ャ劍娅囬梺绋挎湰缁嬫捇宕㈤悽鍛婄厽閹兼番鍨婚埊鏇㈡煥濮樿埖鐓熼煫鍥ュ劤缁嬭崵绱掔紒妯肩畺缂佺粯绻堝畷姗€濡歌缁辨繈姊绘担绛嬪殐闁搞劋鍗冲畷顖炲级閹寸姵娈鹃梺缁樻⒒閳峰牓寮崒鐐寸厱闁抽敮鍋撻柡鍛懅濡叉劕螣鐞涒剝鏂€闂佺粯鍔曞Ο濠囧吹閻斿皝鏀芥い鏃囨閸斻倝鎽堕悙鐑樼厱闁哄洢鍔屾晶顖炴煕濞嗗繒绠婚柡灞界Ч瀹曨偊宕熼鈧▍锝囩磽娴f彃浜炬繝銏f硾椤戝洨绮绘ィ鍐╃厵閻庢稒岣跨粻姗€鏌ㄥ☉妯夹fい銊e劦閹瑩顢旈崟顓濈礄闂備浇顕栭崰鏍礊婵犲倻鏆﹂柟顖炲亰濡茶鈹戦埄鍐ㄧ祷妞ゎ厾鍏樺璇测槈閵忕姈鈺呮煏婢跺牆鍔撮柛鏂款槺缁辨挻鎷呯粙搴撳亾閸濄儳鐭撶憸鐗堝笒閺嬩線鏌熼崜褏甯涢柡鍛倐閺屻劑鎮ら崒娑橆伓 ---闂傚倸鍊搁崐鐑芥倿閿旈敮鍋撶粭娑樺幘濞差亜鐓涢柛娑卞幘椤斿棝姊虹捄銊ユ珢闁瑰嚖鎷�
开发学院软件开发汇编语言 汇编源码系列之free 阅读

汇编源码系列之free

 2008-04-29 09:33:38 来源:WEB开发网 闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷闂傚倸鍊搁崐椋庣矆娓氣偓楠炲鏁撻悩鎻掔€梺姹囧灩閻忔艾鐣烽弻銉︾厵闁规鍠栭。濂告煕鎼达紕校闁靛洤瀚伴獮鎺楀箣濠靛啫浜鹃柣銏⑶圭壕濠氭煙閻愵剚鐏辨俊鎻掔墛缁绘盯宕卞Δ鍐冣剝绻涘畝濠佺敖缂佽鲸鎹囧畷鎺戭潩閹典焦鐎搁梻浣烘嚀閸ゆ牠骞忛敓锟�婵犵數濮烽弫鍛婃叏椤撱垹绠柛鎰靛枛瀹告繃銇勯幘瀵哥畼闁硅娲熷缁樼瑹閳ь剙岣胯鐓ら柕鍫濇偪濞差亜惟闁宠桨鑳堕崝锕€顪冮妶鍡楃瑐闁煎啿鐖奸崺濠囧即閵忥紕鍘梺鎼炲劗閺呮稒绂掕缁辨帗娼忛埡浣锋闂佽桨鐒﹂幑鍥极閹剧粯鏅搁柨鐕傛嫹闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷  闂傚倸鍊搁崐鐑芥嚄閼哥數浠氱紓鍌欒兌缁垶銆冮崨鏉戠厺鐎广儱顦崡鎶芥煏韫囨洖校闁诲寒鍓熷铏圭磼濡搫顫岄梺璇茬箲濮樸劑鍩€椤掍礁鍤柛鎾跺枎椤繐煤椤忓嫬鐎銈嗘礀閹冲酣宕滄导瀛樷拺闂侇偆鍋涢懟顖涙櫠椤斿墽纾煎璺猴功缁夎櫣鈧鍠栭…閿嬩繆濮濆矈妲烽梺绋款儐閹瑰洤螞閸愩劉妲堟繛鍡楃箲濞堟﹢姊绘担椋庝覆缂傚秮鍋撴繛瀛樼矤閸撶喖宕洪埀顒併亜閹烘垵鈧綊寮抽鍕厱閻庯綆浜烽煬顒傗偓瑙勬磻閸楀啿顕i崐鐕佹Ь闂佸搫妫寸粻鎾诲蓟閵娾晜鍋嗛柛灞剧☉椤忥拷
核心提示:这个都是过去DOS时代的汇编源码,虽然已经过去了,汇编源码系列之free,但是对于学习汇编还是有帮助的,汇编语言只是程序员一门基础语言

这个都是过去DOS时代的汇编源码,虽然已经过去了,但是对于学习汇编还是有帮助的,汇编语言只是程序员一门基础语言,大多人掌握即可,不一定要深入研究.......

    name  free
    page  60,132
    title  'FREE --- Report free space on disk'
; FREE --- a utility to report free space on
;     the default or selected disk drive.
;
; Requires PC-DOS or MS-DOS 2.0.
;
; Used in the form:
; A> FREE [unit:]
; (item in square brackets is optional)
;
; version 1.0  July 4, 1984
; Copyright (c) 1984 by Ray Duncan
; May be freely reproduced for non-commercial use.
cr   equ   0dh       ;ASCII carriage return
lf   equ   0ah       ;ASCII line feed
blank  equ  20h    ;ASCII space code
eom  equ  '$'    ;end of string marker
; Here we define a dummy segment containing labels
; for the default file control block and the command tail buffer,
; so that the main program can access those locations.
;
psp  segment para public 'PSP' 
  org  05ch
fcb  label  byte    ;default file control block
  org  080h
command  label  byte    ;default command buffer
psp  ends
cseg  segment  para public 'CODE'
  assume  cs:cseg,ds:psp,es:data,ss:stack
get_drive proc  near    ;get drive selection, if any,
        ;otherwise obtain the identity
        ;of the current disk drive.
        ;Return drive (1=A, 2=B, etc) in AL.
        ;
  mov   al,fcb      ;Pick up the drive code, parsed
        ;by DOS into the default file
        ;control block.
  or  al,al    ;Is it the default?
  jnz  get_drive1  ;no, use it
  mov  ah,19h    ;Yes, get the actual current
  int  21h    ;drive from PC-DOS.
  inc   al    ;Increment to match FCB code.
get_drive1:      ;Return drive code in AL.
  ret
get_drive endp
free   proc  far       ;entry point from PC-DOS
    push  ds       ;save DS:0000 for final
    xor   ax,ax      ;return to PC-DOS
    push  ax
    mov   ax,data     ;make our data segment
    mov   es,ax      ;addressable via ES register.
    mov   ah,30h    ;check version of PC-DOS.  
    int   21h
    cmp   al,2
    jae   free1    ;proceed, DOS 2.0 or greater.
    mov   dx,offset msg2 ;DOS 1.x --- print error message
  mov  ax,es    ;and exit. First fix up DS register
  mov  ds,ax    ;so error message is addressable.
  jmp  free4
free1: call  get_drive   ;get drive selection into DL.
  push  es    ;copy ES to DS for remainder
  pop  ds    ;of the program...
  assume  ds:data    ;and tell assembler about it.
  mov  dl,al    
  add  al,'A'-1  ;form drive letter from drive code,
  mov  outputb,al  ;and put it into the output string.
  mov  ah,36h    ;now call DOS to get free disk space.
  int  21h
  cmp  ax,-1    ;was drive invalid?
  je  free3    ;yes,go print error message
        ;drive was ok, so now registers are...
        ;AX=number of sectors per cluster
        ;BX=available clusters,
        ;CX=number of bytes per sector,
        ;DX=total clusters per drive.
        ;calculate free space:
  mul  cx    ;sectors per cluster * bytes per sector
        ;(we assume this won't overflow into DX)
  mul  bx    ;then * available clusters
        ;DX:AX now contains free space in bytes.
        ;SI = last byte address for converted string.
  mov  si,offset (outputa+9)
  mov  cx,10    ;CX = 10, radix for conversion
  call  bin_to_asc  ;convert free space value to ASCII,
  mov  dx,offset output
  jmp  free4    ;and print it out.
free3: mov   dx,offset msg1 ;illegal drive, print error
free4:  mov  ah,9    ;print the string whose address
  int  21h    ;is in DX.
  ret      ;then return to DOS.
free  endp
; Convert 32 bit binary value to ASCII string.
;
; Call with DX:AX = signed 32 bit value
;     CX  = radix
;      SI  = last byte of area to store resulting string
;         (make sure enough room is available to store
;       the string in the radix you have selected.)
;
; Destroys AX, BX, CX, DX, and SI.
;
bin_to_asc proc  near    ;convert DX:AX to ASCII.
        ;force storage of at least 1 digit.
  mov  byte ptr [si],'0'
  or  dx,dx    ;test sign of 32 bit value,
  pushf      ;and save sign on stack.
  jns  bin1    ;jump if it was positive.
  not  dx    ;it was negative, take 2's complement
  not  ax    ;of the value.
  add  ax,1
  adc  dx,0
bin1:        ;divide the 32 bit value by the radix
        ;to extract the next digit for the
        ;forming string.
  mov  bx,ax    ;is the value zero yet?
  or  bx,dx
  jz  bin3    ;yes, we are done converting.
  call  divide    ;no, divide by radix.
  add  bl,'0'    ;convert the remainder to an ASCII digit.
  cmp  bl,'9'    ;we might be converting to hex ASCII,
  jle  bin2    ;jump if in range 0-9,
  add  bl,'A'-'9'-1  ;correct it if in range A-F.
bin2:  mov  [si],bl    ;store this character into string.
  dec  si    ;back up through string,
  jmp  bin1    ;and do it again.
bin3:        ;restore sign flag,
  popf      ;was original value negative?
  jns  bin4    ;no, jump
        ;yes,store sign into output string.
  mov  byte ptr [si],'-'
bin4:  ret      ;back to caller.
bin_to_asc endp
; General purpose 32 bit by 16 bit unsigned divide.
; This must be used instead of the plain machine unsigned divide
; for cases where the quotient may overflow 16 bits (for example,
; dividing 100,000 by 2). If called with a zero divisor, this
; routine returns the dividend unchanged and gives no warning.
;
; Call with DX:AX = 32 bit dividend
;      CX  = divisor
;
; Returns  DX:AX = quotient
;      BX  = remainder
;    CX  = divisor (unchanged)
;
divide  proc  near    ; Divide DX:AX by CX
  jcxz  div1    ; exit if divide by zero
  push  ax    ; 0:dividend_upper/divisor
  mov  ax,dx
  xor  dx,dx
  div  cx
  mov  bx,ax    ; BX = quotient1
  pop  ax    ; remainder1:dividend_lower/divisor
  div  cx
  xchg  bx,dx    ; DX:AX = quotient1:quotient2
div1:  ret      ; BX = remainder2
divide  endp
cseg  ends
data  segment para public 'DATA'
output    db  cr,lf
outputa    db  10 dup (blank)
    db  ' bytes free on drive '
outputb    db  'x:',cr,lf,eom
msg1      db   cr,lf
        db   'That disk drive does not exist.'
        db   cr,lf,eom
msg2      db   cr,lf
        db   'Requires DOS version 2 or greater.'
        db   cr,lf,eom
data  ends  
stack  segment para stack 'STACK'
    db   64 dup (?)
stack  ends
    end   free


Tags:汇编 源码 系列

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接