;////////////////////////////////////////////////////////////////// ;Program Name:PCIV.asm ;Author:Clark Xie ;date: ;Description:Print configration data ;////////////////////////////////////////////////////////////////// ;History: ;30/10/2007 14:30 V0.1.4 Clark Xie update a small bug of PRINT_READ_DATA ;30/10/2007 09:10 V0.1.3 Clark Xie add check mechanism of input types of CMD & HEX ;30/10/2007 08:20 V0.1.2 Clark Xie add X,Y coordinates to 'V' cmd ;29/10/2007 16:40 V0.1.1 Clark Xie add cmd 'V' ;29/10/2007 13:50 v0.1.0 Clark Xie update a small bug ;29/10/2007 11:50 V0.0.9 Clark Xie Update a important bug:the arithmetic of MAKE_ADDRESS2 ;26/10/2007 15:40 V0.0.8 Clark Xie Modify some bugs(GET_HEX input type) ;26/10/2007 11:00 V0.0.7 Clark Xie Add MACRO PUTC and PUTS ;26/10/2007 10:00 V0.0.6 Clark Xie Implement CMD 'I','Q','?',change File Name to PCIV ;25/10/2007 15:40 V0.0.5 Clark Xie Can input BUS# DEV# FUN# REG# respectively ;25/10/2007 15:40 V0.0.4 Clark Xie Can show 4 registers data ;25/10/2007 14:20 v0.0.3 Clark Xie Can input a DoubleWord hex(addreess value) to show configration register data ;24/10/2007 16:20 V0.0.2 Clark Xie separate BUS_NUM,DEV_NUM,FUN_NUM,REG_NUM from a entire DWORD ADDRESS_VALUE(MK_ADRRES) ;24/10/2007 13:00 v0.0.1 Clark Xie Read DATA from Bus#0,Device#0,Function#0,Register#8 of S39 ;////////////////////////////////////////////////////////////////// .386 ;----------------------------------------------------------------- ; this macro prints a char in AL and advances ; the current cursor position: PUTC MACRO char PUSH AX MOV AL, char MOV AH, 0Eh INT 10h POP AX ENDM PUTS MACRO str PUSH AX PUSH DX mov ah,9 mov dx,offset str int 21h POP DX POP AX endm ;------------------------------------------ ;MACRO:PRINT_A_DWORD ;input:READ_DATA ;output:print data in DDWORD_DATA PRINT_A_DWORD MACRO DDWORD_DATA PUSH EDX PUSH ECX MOV EDX,DDWORD_DATA MOV CL,4D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,DDWORD_DATA and dl,0FH call PRINT_ASCII_DL PUTC ' ' MOV EDX,DDWORD_DATA MOV CL,12D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,DDWORD_DATA MOV CL,8D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL PUTC ' ' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV EDX,DDWORD_DATA MOV CL,20D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,DDWORD_DATA MOV CL,16D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL PUTC ' ' MOV EDX,DDWORD_DATA MOV CL,28D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,DDWORD_DATA MOV CL,24D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL PUTC ' ' ;PUTS RETURN POP ECX POP EDX endm ;----------------------------------------------------------------- SSEG SEGMENT PARA STACK DW 256 dup (?) SSEG ENDS DSEG SEGMENT USE16 HEAD_MSG DB 'PCI bus Configration Space Simple Viewer(PCIV) - [v0.1.4]',13,10 db 'CopyRight (c) Clark Xie 2007',13,10 db 'type ? for more information.',13,10,'$' MSG_WARNNING DB 'WARNNING:There is something wrong with your input!',13,10,'$' HELP_MSG DB '---------------------------------------------------------',13,10 DB 'L - List all available PCI BUSes',13,10 DB 'I - Input appointed BUS# DEV# FUN# REG# to view REGISTER',13,10 DB 'V - View 256BYTES REGISTERS using BUS# DEV# FUN#',13,10 DB 'Q - Quit',13,10 DB '---------------------------------------------------------',13,10 DB '$' MSG_LIST_HEAD DB 'Bus# | Dev# | Fun# | Vendor | Device | Revi | Class Code ',13,10,'$' MSG_REG_HEAD DB 'Bus# | Dev# | Fun# | REGISTER# ','$' MSG_X_LINE DB 'HL 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F',13,10,'$' MSG_WRONG_INPUT DB 'ERROR:Wrong input! Must be like "00" & a Hex!',13,10 DB 'Please input Number again.[Q] to Quit.',13,10,'-$' MSG_INPUT_BUSNO DB 'Input the BUS Number:',13,10,'-','$' MSG_INPUT_DEVNO DB 'Input the DEV Number:',13,10,'-','$' MSG_INPUT_FUNNO DB 'Input the FUN Number:',13,10,'-','$' MSG_INPUT_REGNO DB 'Input the REG Number:',13,10,'-','$' SLASH DB ' | ','$' MSG_CMD DB '-','$' RETURN db 13,10,'$' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PCI_CONFIG_ADDRESS_PORT = 0CF8h PCI_CONFIG_DATA_PORT = 0CFCh READ_DATA dd 0 READ_DATA1 dd 0 READ_DATA2 DD 0 READ_DATA3 DD 0 READ_DATA4 DD 0 INPUT_STR DB 5 DUP(0) ADDRESS_VALUE DD 0 BUS_NUM DD 0 DEV_NUM DD 0 FUN_NUM DD 0 REG_NUM DD 0 TEMP DD 0 BUS_VAR DD 0 DEV_VAR DD 0 FUN_VAR DD 0 PDI_BUS_SHIFT = 8 PDI_BUS_SIZE = 8 PDI_BUS_MAX = 0FFH ;256个bus PDI_BUS_MASK = 0FF00H PDI_DEVICE_SHIFT = 3 PDI_DEVICE_SIZE = 5 PDI_DEVICE_MAX = 1FH ;32个device PDI_DEVICE_MASK = 00F8H PDI_FUNCTION_SHIFT = 0 PDI_FUNCTION_SIZE = 3 PDI_FUNCTION_MAX = 7H ;8个function PDI_FUNCTION_MASK = 0007H COUNT DB ? DSEG ends ;//////////////////////////////////////////////////////////////////// CSEG SEGMENT USE16 ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX BEGIN: PUTS RETURN PUTS RETURN PUTS HEAD_MSG CMD_TIP: PUTS MSG_CMD XOR SI,SI GET_CHAR_START: CALL GET_CHAR CMP AL,13 JZ GET_CHAR_END CMP AL,27 ;ESC JZ OVER MOV INPUT_STR[SI],AL INC SI JMP GET_CHAR_START GET_CHAR_END: PUTS RETURN CMP INPUT_STR[0],3FH ;?-Help JZ PRINT_HELP_MSG CMP INPUT_STR[0],71H ;q-quit JZ OVER CMP INPUT_STR[0],51H ;Q-quit JZ OVER CMP INPUT_STR[0],6CH ;l-List JZ LIST_ALL_BUS CMP INPUT_STR[0],4CH ;L-List JZ LIST_ALL_BUS CMP INPUT_STR[0],69H ;i-Input JZ INPUT_BDFR CMP INPUT_STR[0],49H ;I-Input JZ INPUT_BDFR CMP INPUT_STR[0],56H ;v-Input JZ VIEW_BDFR CMP INPUT_STR[0],76H ;V-Input JZ VIEW_BDFR PUTS MSG_WARNNING JMP BEGIN PRINT_HELP_MSG: PUTS HELP_MSG JMP CMD_TIP INPUT_BDFR: CALL MAKE_ADDRESS ;GET ADDRESS_VALUE --OK! PUTS RETURN mov dx,PCI_CONFIG_ADDRESS_PORT ;MOV EAX,80007800h OUT DX,EAX ;read READ_DATA from PCI_CONFIG_DATA register mov dx,PCI_CONFIG_DATA_PORT IN EAX,DX MOV READ_DATA,EAX ;save read result to READ_DATA CALL PRINT_READ_DATA2 PUTS RETURN JMP CMD_TIP VIEW_BDFR: CALL GET_ADDRESS_VALUE ;BUS# DEV# FUN# PUTS RETURN PUTS MSG_X_LINE REG_NUM_LOOP: XOR EBX,EBX MOV EBX,REG_NUM AND EBX,00FH CMP EBX,000H JZ PRINT_Y_LINE Y_LINE_RETURN: MOV DX,PCI_CONFIG_ADDRESS_PORT ;MOV EAX,ADDRESS_VALUE OUT DX,EAX MOV DX,PCI_CONFIG_DATA_PORT IN EAX,DX MOV READ_DATA,EAX PRINT_A_DWORD READ_DATA MOV EBX,REG_NUM AND EBX,0FFH CMP EBX,0FCH JAE BEGIN AND EBX,00FH CMP EBX,00CH JZ ENTER_RETRUN JMP INC_REG_NUM PRINT_Y_LINE: MOV EDX,REG_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL PUTC '0' PUTC ' ' JMP Y_LINE_RETURN ENTER_RETRUN: PUTS RETURN INC_REG_NUM: ADD REG_NUM,4 CALL MAKE_ADDRESS2 JMP REG_NUM_LOOP LIST_ALL_BUS: PUTS MSG_LIST_HEAD MOV ADDRESS_VALUE,00000000H MOV BUS_NUM,00000000H LOOP1: MOV DEV_NUM,00000000H LOOP2: MOV FUN_NUM,00000000H LOOP3: MOV REG_NUM,00000000H CALL MAKE_ADDRESS2 MOV DX,PCI_CONFIG_ADDRESS_PORT ;MOV EAX,ADDRESS_VALUE OUT DX,EAX MOV DX,PCI_CONFIG_DATA_PORT IN EAX,DX MOV READ_DATA1,EAX ;XOR EAX,EAX ;ADD REG_NUM,4H ;CALL MAKE_ADDRESS2 ;MOV DX,PCI_CONFIG_ADDRESS_PORT ;MOV EAX,ADDRESS_VALUE ;OUT DX,EAX ;MOV DX,PCI_CONFIG_DATA_PORT ;IN EAX,DX ;MOV READ_DATA2,EAX XOR EAX,EAX ADD REG_NUM,8H CALL MAKE_ADDRESS2 MOV DX,PCI_CONFIG_ADDRESS_PORT ;MOV EAX,ADDRESS_VALUE OUT DX,EAX MOV DX,PCI_CONFIG_DATA_PORT IN EAX,DX MOV READ_DATA2,EAX MOV EAX,READ_DATA1 CMP AX,0FFFFH ;INVALID VENDOR ID JZ INVALID_VENDOR CALL PRINT_READ_DATA INVALID_VENDOR: INC FUN_NUM CMP FUN_NUM,00000008H JZ FUN_FULL JMP LOOP3 FUN_FULL: ;MOV FUN_NUM,00H INC DEV_NUM CMP DEV_NUM,00000020H JZ DEV_FULL JMP LOOP2 ; ;MOV DEV_NUM,00H DEV_FULL: INC BUS_NUM CMP BUS_NUM,000000FFH JZ BEGIN JMP LOOP1 OVER: ;POP EBX mov ah,4ch int 21h ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;------------------------------------------ ;Funciton:PRINT_ASCII_DL ;input:dl ;output:convert HEX to ASCII PRINT_ASCII_DL proc near PUSH EAX cmp dl,0AH jge gea add dl,'0' cmp dl,'9' jbe ok add dl,7 jmp ok gea: add dl,37H ;'A'-0AH ok: mov ah,2 int 21h POP EAX ret PRINT_ASCII_DL endp ;------------------------------------------ ;Funciton:PRINT_DL ;input:DL ;output:DL WITH HEX PRINT_DL proc near PUSH EAX MOV AH,6 INT 21H POP EAX ret PRINT_DL endp ;------------------------------------------ ;Funciton:PRINT_READ_DATA ;input:READ_DATA1,READ_DATA2 ;output:print data in READ_DATA,low--high PRINT_READ_DATA proc near DISPLAY: ;PRINT BUS_NUM MOV EDX,BUS_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,BUS_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS SLASH ;PRINT DEV_NUM MOV EDX,DEV_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,DEV_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS SLASH ;PRINT FUN_NUM MOV EDX,FUN_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,FUN_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS SLASH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;VENDOR ID MOV EDX,READ_DATA1 MOV CL,12D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA1 MOV CL,8D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA1 MOV CL,4D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA1 and dl,0FH call PRINT_ASCII_DL ;DEVICE ID PUTS SLASH MOV EDX,READ_DATA1 MOV CL,28D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA1 MOV CL,24D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA1 MOV CL,20D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA1 MOV CL,16D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL PUTS SLASH ;REVISION ID MOV EDX,READ_DATA2 MOV CL,4D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA2 and dl,0FH call PRINT_ASCII_DL PUTS SLASH ;CLASS CODE MOV EDX,READ_DATA2 MOV CL,28D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA2 MOV CL,24D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA2 MOV CL,20D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA2 MOV CL,16D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA2 MOV CL,12D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA2 MOV CL,8D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL PUTS RETURN RET PRINT_READ_DATA endp ;------------------------------------------ ;Funciton:READ_DATA2 ;input:READ_DATA ;output:print data in READ_DATA,low--high PRINT_READ_DATA2 proc near PUTS MSG_REG_HEAD ;;PRINT REG_NUM MOV EDX,REG_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,REG_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS RETURN ;;;;; MOV EDX,BUS_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,BUS_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS SLASH ;PRINT DEV_NUM MOV EDX,DEV_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,DEV_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS SLASH ;PRINT FUN_NUM MOV EDX,FUN_NUM MOV CL,4D SHR EDX,CL AND DL,0FH CALL PRINT_ASCII_DL MOV EDX,FUN_NUM AND DL,0FH CALL PRINT_ASCII_DL PUTS SLASH ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV EDX,READ_DATA MOV CL,12D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA MOV CL,8D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA MOV CL,4D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA and dl,0FH call PRINT_ASCII_DL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PUTC ' ' MOV EDX,READ_DATA MOV CL,28D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA MOV CL,24D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA MOV CL,20D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL MOV EDX,READ_DATA MOV CL,16D SHR EDX,CL and dl,0FH call PRINT_ASCII_DL PUTS RETURN RET PRINT_READ_DATA2 endp ;------------------------------------------ ;Funciton:GET_HEX ;input: ;output:EBX ;Description:input a hex from keybord into EBX GET_HEX PROC NEAR PUSH EAX PUSH EDX ;MOV TEMP,00000000H ;PUSH EBX PUSH SI GET_HEX_STRT: XOR EBX,EBX XOR SI,SI ;AND TEMP,00000000H MOV COUNT,00H GET_HEX_WAIT: MOV AH,1 INT 16H JZ GET_HEX_WAIT ;CACHE EMPTY MOV AH,0 ;读键盘输入,结果以ascii码的形式保存在AL INT 16H MOV DL,AL ;将AL打印输出 CALL PRINT_DL cmp al, 13 ;将输入和回车比较 JZ GET_HEX_NEXT ;输入是回车则跳转 CMP AL,'Q' JZ GET_HEX_OVER CMP AL,'q' JZ GET_HEX_OVER ;CALL PRINT_DL ;and eax,0000000FH CMP AL,2FH ; '0' JBE WRONG_INPUT_HEX CMP AL,39H ; '9' JAE BIGGER_THAN_9 ;CMP AL,47H ;JAE BIGGER_THAN_A ;CMP AL,30H RIGHT_IMPUT: CALL ASCII2Hex_AL ;将AL转化为16进制 AND EAX,0000000FH ;MOV EBX,EAX OR EBX,EAX ;将AL保存到ebx低4位:BL ;CMP BL,47H ;JG WRONG_INPUT_HEX INC SI CMP SI,2 JZ GET_HEX_WAIT ;JB WRONG_INPUT_HEX MOV CL,4 SHL EBX,CL ;EBX左移四位 JMP GET_HEX_WAIT ;继续读输入 WRONG_INPUT_HEX: PUTS RETURN PUTS MSG_WRONG_INPUT JMP GET_HEX_STRT BIGGER_THAN_9: CMP AL,41H ;'A' JB WRONG_INPUT_HEX CMP AL,47H ;>'F' JAE BIGGER_THAN_F JMP RIGHT_IMPUT BIGGER_THAN_F: CMP AL,60H ;<'a' JBE WRONG_INPUT_HEX CMP AL,67H ;>'f' JAE WRONG_INPUT_HEX JMP RIGHT_IMPUT GET_HEX_NEXT: CMP SI,2 JB WRONG_INPUT_HEX GET_HEX_OVER: POP SI ;POP EBX POP EDX POP EAX RET GET_HEX ENDP ;------------------------------------------ ;Funciton:GET_CHAR ;input:KEYBOARD ;output:AL GET_CHAR PROC NEAR PUSH EDX WAIT_FOR_KEY2: MOV AH,1 INT 16H JZ WAIT_FOR_KEY2 ;CACHE EMPTY MOV AH,0 ;读键盘输入,结果以ascii码的形式保存在AL INT 16H MOV DL,AL ;将AL打印输出 CALL PRINT_DL POP EDX NEXT2: RET GET_CHAR ENDP ;------------------------------------------ ;Funciton:ASCII2Hex_AL ;input:AL ;output:AL CONVERT ASCII TO HEX ASCII2Hex_AL PROC NEAR CMP AL,41H ;'A' JGE ABCDEF SUB AL,30H RET ABCDEF: SUB AL,37H RET ASCII2Hex_AL ENDP ;---------------------------------------- ;FUNCTION:GET_ADDRESS_VALUE ;INPUT:BUS_NUM,DEV_NUM,FUN_NUM:ebx ;OUTPUT:EAX GET_ADDRESS_VALUE PROC NEAR PUSH EDX PUSH EBX ;AND ADDRESS_VALUE,00000000H XOR EAX,EAX PUTS RETURN PUTS MSG_INPUT_BUSNO CALL GET_HEX MOV BUS_NUM,EBX MOV CL,16D ROL EBX,CL MOV EAX,EBX PUTS RETURN ;--------------------------------------- PUTS MSG_INPUT_DEVNO CALL GET_HEX MOV DEV_NUM,EBX MOV CL,11D ;SHL EAX,CL ROL EBX,CL AND EBX,0F800H OR EAX,EBX PUTS RETURN ;--------------------------------------- PUTS MSG_INPUT_FUNNO CALL GET_HEX MOV FUN_NUM,EBX MOV CL,8D ;SHL EAX,CL ROL EBX,CL AND EBX,00700H OR EAX,EBX PUTS RETURN ;--------------------------------------- ;PUTS MSG_INPUT_REGNO ;CALL GET_HEX MOV REG_NUM,00000000H ;OR EAX,EBX OR EAX,80000000H PUTS RETURN POP EBX POP EDX ;POP EAX ret GET_ADDRESS_VALUE endp ;---------------------------------------- ;FUNCTION:MAKE_ADDRESS ;INPUT:BUS_NUM,DEV_NUM,FUN_NUM,REG_NUM:ebx ;OUTPUT:EAX MAKE_ADDRESS PROC NEAR ;PUSH EAX PUSH EDX PUSH EBX ;AND ADDRESS_VALUE,00000000H XOR EAX,EAX PUTS RETURN PUTS MSG_INPUT_BUSNO CALL GET_HEX MOV BUS_NUM,EBX MOV CL,16D ROL EBX,CL MOV EAX,EBX PUTS RETURN ;--------------------------------------- PUTS MSG_INPUT_DEVNO CALL GET_HEX MOV DEV_NUM,EBX MOV CL,11D ;SHL EAX,CL ROL EBX,CL AND EBX,0F800H OR EAX,EBX PUTS RETURN ;--------------------------------------- PUTS MSG_INPUT_FUNNO CALL GET_HEX MOV FUN_NUM,EBX MOV CL,8D ;SHL EAX,CL ROL EBX,CL AND EBX,00700H OR EAX,EBX PUTS RETURN ;--------------------------------------- PUTS MSG_INPUT_REGNO CALL GET_HEX MOV REG_NUM,EBX OR EAX,EBX OR EAX,80000000H PUTS RETURN POP EBX POP EDX ;POP EAX ret MAKE_ADDRESS endp ;---------------------------------------- ;FUNCTION:MAKE_ADDRESS2 ;INPUT:BUS_NUM,DEV_NUM,FUN_NUM,REG_NUM:ebx ;OUTPUT:EAX MAKE_ADDRESS2 PROC NEAR PUSH EBX ;PUSH ECX XOR EAX,EAX MOV EBX,BUS_NUM MOV CL,16D ROL EBX,CL MOV EAX,EBX MOV EBX,DEV_NUM MOV CL,11D ;SHL EAX,CL ROL EBX,CL AND EBX,0F800H OR EAX,EBX MOV EBX,FUN_NUM MOV CL,8D ;SHL EAX,CL ROL EBX,CL AND EBX,00700H OR EAX,EBX OR EAX,REG_NUM OR EAX,80000000H ;PUSH ECX POP EBX ret MAKE_ADDRESS2 endp cseg ends end start