flat assembler
Message board for the users of flat assembler.

Index > Main > Conversion from TASM to FASM - Some Help for a Newbie

Author
Thread Post new topic Reply to topic
robink



Joined: 17 Sep 2003
Posts: 14
robink 23 Sep 2003, 22:49
I am trying to convert the following code to FASM. It compiles fine but does not execute without errors. I know everyone is busy but any guidance you can provide would really be appreciated. Here is the code that compiles clean:

Code:
;       cpuid.asm
;
;       CPU detector program.
;
;       Copyright (c) 1993 by Borland International, Inc.
;
;       Build with the provided makefile: make -B

    format MZ
   use16
       org 100h

saved_cpuid     dd      ?
vendor_id          db      ?
cpu_type           db      ?
themodel           db      ?
stepping           db      ?
id_flag            db      0
intel_proc db      0
id_msg             db      "This system has a$"
c8086         db      "n 8086/8088 microprocessor$"
c286         db      "n Intel 286 microprocessor$"
c386         db      "n Intel386 (TM) microprocessor$"
c486             db      "n Intel486 (TM) DX microprocessor$"
Pentium               db      " Pentium(TM) microprocessor", 13, 10, "$"
intel         db      "This system contains a Genuine Intel Processor", 13, 10, "$"
modelmsg   db      "Model:         $"
steppingmsg     db      "Stepping:      $"
familymsg       db      "Processor Family: $"
period               db      ".",13,10,"$"
dataCR             db      ?,13,10,"$"
intel_id               db      "GenuineIntel"


        ; This part of the program must run on an 8086
start:    mov     ax,ds
       mov     ds, ax                  ;set segment register
       mov     es, ax                  ;set segment register
       and     sp, not 3               ;align stack to avoid AC fault
      call    get_cpuid
   call    print
       mov     ax,4c00h                ; terminate program
 int     21h

get_cpuid:

;       8086 CPU check
;       Bits 12-15 are always set on the 8086 processor
;
check_8086:
  pushf                           ;save FLAGS
 pop     bx                      ;store FLAGS in BX
  mov     ax, 0fffh               ;clear bits 12-15
   and     ax, bx                  ;  in FLAGS
 push    ax                      ;store new FLAGS calue on stack
     popf                            ;replace current FLAGS value
        pushf                           ;set new flags
      pop     ax                      ;store new flags in AX
      and     ax, 0f000h              ;if bits 12-15 are set, then CPU
    cmp     ax, 0f000h              ;  is an 8086/8088
  mov     [cpu_type],0             ; save the CPU type
        je      end_get_cpuid


;
;       Intel 286 CPU check
;       Bits 12-15 are always clear on the Intel processor.
;
check_80286:

   or      bx, 0f000h              ;try to set bits 12-15
      push    bx
  popf
        pushf
       pop     ax
  and     ax, 0f000h              ; if bits 12-15 are cleared,
                                        ;       CPU=Intel 286
       mov     [cpu_type], 2             ; turn on Intel 286 Cpu flag
      jz      end_get_cpuid           ; if CPU is intel 286, check
                                        ; for Intel 287 math coprocessor

;       Intel386 CPU check
;       The AC bit (bit 1Cool, is a new bit introduced in the EFLAGS
;       register on the Intel486 DX CPU to generate alignment faults.
;       This bit can not be set on the Intel386 CPU.
;
check_intel386:

       pushfd
      pop     eax                     ;get original EFLAGS
        mov     ecx,eax                 ; save original EFLAGS
      xor     eax,40000h              ;flip AC bit in EFLAGS
      push    eax                     ; save for EFLAGS
   popfd                           ; copy to EFLAGS
    pushfd                          ; push EFLAGS
       pop     eax                     ; get new EFLAGS value
      xor     eax,ecx                 ; can't toggle AC bit, CPU=Intel386
        mov     [cpu_type], 3             ; turn on Intel386 CPU flag
       je      end_get_cpuid           ; if CPU is Intel386, now check
                                     ; for an Intel 287 or Intel387 MCP

;     Intel486 DX CPU, Intel 487 SX MCP, and Intel486 SX CPU checking
;
;     Checking for the ability to set/clear the ID flag (bit 21) in EFLAGS
;     which diferentiates between Pentium (or greater) and the Intel486.
;     If the ID flag is set then the CPUID instruction can be used to
;     determine the final version of the chip, else it's a 486
;
;
check_Intel486:

 mov     [cpu_type], 4             ;turn on Intel486 CPU flag
        pushfd                          ;push original EFLAGS
       pop     eax                     ; get original EFLAGS in eax
        mov     ecx,eax                 ;save original EFLAGS in ecx
        or      eax,200000h             ; flip ID bit in EFLAGS
     push    eax                     ;save for EFLAGS
    popfd                           ;copy to EFLAGS
     pushfd                          ;push EFLAGS
        pop     eax                     ;get new EFLAGS value
       xor     eax,ecx
     je      end_get_cpuid           ;if ID bit cannot be changed,
                                       ;CPU=Intel486 without CPUID
                                 ;instruction functionality

;       Otherwise, execute CPUID instruction to determine vendor,
;       family, model and stepping.

check_vendor:

 mov     [id_flag], 1              ; set flag for indicating use of
                                  ;CPUID inst
 mov     eax, 0                  ;set up for CPUID instruction
       cpuid
       mov     dword ptr vendor_id, ebx; Test for "GenuineIntel" vendor id.
      mov     dword ptr vendor_id+4, edx
  mov     dword ptr vendor_id+8, ecx
  mov     si, vendor_id
       mov     di, intel_id     ;RJK should be the length
  mov     cx, intel_id
compare:
    repe    cmpsb
       cmp     cx, 0                   ; must be a GenuineIntel if ecx =0
  jne     cpuid_data

intel_processor:
  mov     [intel_proc], 1
     mov     [intel-1], ' '                ; add a space so the Genuine Intel
                                  ; message prints out.

cpuid_data:
    mov     eax, 1
      cpuid
       mov     [saved_cpuid],eax         ;save for future use
      and     eax, 0F00H              ; mask everything but family
        shr     eax, 8
      mov     [cpu_type], al            ; set cpu_type with family

    mov     eax,saved_cpuid         ;restore data
       mov     [stepping], al
      and     [stepping], 0FH           ; isolate stepping info

       mov     eax, saved_cpuid
    mov     [themodel], al
      and     [themodel], 0F0H          ; isolate model info
      shr     [themodel], 4

end_get_cpuid:

     ret


;
;       This procedure prints the appropriate cpuid string
;       If the CPUID instruction was supported, it prints out
;       the cpuid info.

print:
    push    ax
  push    bx
  push    cx
  push    dx
  cmp     [id_flag], 1              ; if set to 1, cpu supported CPUID
                                        ; instruction
                                       ; print detailed CPUID information
  je      print_cpuid_data

        mov     dx,id_msg
   mov     ah, 9h
      int     21h         ; print initial message
 ret

print_86:
        cmp     [cpu_type], 0
       jne     print_286
   mov     dx,c8086
    mov     ah, 9h
      int     21h
 jmp     end_print

print_286:
 cmp     [cpu_type], 2
       jne     print_386
   mov     dx, c286
    mov     ah, 9h
      int     21h
 jmp     end_print


print_386:
     cmp     [cpu_type], 3
       jne     print_486
   mov     dx,c386
     mov     ah, 9h
      int     21h
 jmp     end_print


print_486:
     mov     dx, c486
    mov     ah, 9h
      int     21h
 jmp     end_print

print_cpuid_data:

      cmp     [cpu_type], 5
       jne     print_cpuid_cont

        mov     dx, Pentium
 mov     ah, 9
       int     21h

print_cpuid_cont:
        mov     dx, familymsg    ;print family msg
  mov     ah, 9h
      int     21h
 mov     al, [cpu_type]
      mov     byte ptr dataCR, al
 add     byte ptr dataCR, 30H    ; convert to ASCII
  mov     dx,  dataCR      ; print family info
        mov     ah, 9h
      int     21h

     mov     dx, steppingmsg  ; print stepping msg
       mov     ah, 9h
      int     21h
 mov     al, [stepping]
      mov     byte ptr dataCR, al
 add     byte ptr dataCR, 30H    ; convert to ASCII
  mov     dx, dataCR       ; print stepping info
      mov     ah, 9h
      int     21h

     mov     dx, modelmsg     ; print model msg
  mov     ah, 9h
      int     21h
 mov     al, [themodel]
      mov     byte ptr dataCR, al
 add     byte ptr dataCR, 30H    ; convert to ASCII
  mov     dx, dataCR       ; print stepping info
      mov     ah, 9h
      int     21h
end_print:
   pop     dx
  pop     cx
  pop     bx
  pop     ax
  ret
    


This code is from the examples that come with TASM. Thanks in advance.

_________________
Thanks,

Robin
Post 23 Sep 2003, 22:49
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 24 Sep 2003, 06:29
OK, try this one. It works somehow, maybe wrong, but works. Smile
Mainly you must change "dword ptr XXXX" to "dword [XXXX]".

Example:
Use: mov eax, somelabel ; Put address of somelabel to eax
mov eax, [somelabel] ; Put content of memory on "somelabel" to eax.


Code:
; cpuid.asm
;
; CPU detector program.
;
; Copyright (c) 1993 by Borland International, Inc.
;
; Build with the provided makefile: make -B

        use16        ; Com file not exe.
        org 100h


; This part of the program must run on an 8086
start:
        mov     ax,ds
        mov     ds, ax          ;set segment register
        mov     es, ax          ;set segment register
        and     sp, not 3       ;align stack to avoid AC fault
        call    get_cpuid
        call    print
        mov     ax,4c00h        ; terminate program
        int     21h

get_cpuid:

; 8086 CPU check
; Bits 12-15 are always set on the 8086 processor
;
check_8086:
        pushf                   ;save FLAGS
        pop   bx                ;store FLAGS in BX
        mov   ax, 0fffh         ;clear bits 12-15
        and   ax, bx            ; in FLAGS
        push  ax                ;store new FLAGS calue on stack
        popf                    ;replace current FLAGS value
        pushf                   ;set new flags
        pop   ax                ;store new flags in AX
        and   ax, 0f000h        ;if bits 12-15 are set, then CPU
        cmp   ax, 0f000h        ; is an 8086/8088
        mov   [cpu_type],0      ; save the CPU type
        je    end_get_cpuid


;
; Intel 286 CPU check
; Bits 12-15 are always clear on the Intel processor.
;
check_80286:

        or      bx, 0f000h      ;try to set bits 12-15
        push    bx
        popf
        pushf
        pop     ax
        and     ax, 0f000h      ; if bits 12-15 are cleared,

; CPU=Intel 286
        mov     [cpu_type], 2   ; turn on Intel 286 Cpu flag
        jz      end_get_cpuid   ; if CPU is intel 286, check

; for Intel 287 math coprocessor

; Intel386 CPU check
; The AC bit (bit 1, is a new bit introduced in the EFLAGS
; register on the Intel486 DX CPU to generate alignment faults.
; This bit can not be set on the Intel386 CPU.
;
check_intel386:

        pushfd
        pop     eax             ;get original EFLAGS
        mov     ecx,eax         ; save original EFLAGS
        xor     eax,40000h      ;flip AC bit in EFLAGS
        push    eax             ; save for EFLAGS
        popfd                   ; copy to EFLAGS
        pushfd                  ; push EFLAGS
        pop     eax             ; get new EFLAGS value
        xor     eax,ecx         ; can't toggle AC bit, CPU=Intel386
        mov     [cpu_type], 3   ; turn on Intel386 CPU flag
        je      end_get_cpuid   ; if CPU is Intel386, now check

; for an Intel 287 or Intel387 MCP

; Intel486 DX CPU, Intel 487 SX MCP, and Intel486 SX CPU checking
;
; Checking for the ability to set/clear the ID flag (bit 21) in EFLAGS
; which diferentiates between Pentium (or greater) and the Intel486.
; If the ID flag is set then the CPUID instruction can be used to
; determine the final version of the chip, else it's a 486
;
;
check_Intel486:

        mov    [cpu_type], 4    ;turn on Intel486 CPU flag
        pushfd                  ;push original EFLAGS
        pop    eax              ; get original EFLAGS in eax
        mov    ecx,eax          ;save original EFLAGS in ecx
        or     eax,200000h      ; flip ID bit in EFLAGS
        push   eax              ;save for EFLAGS
        popfd                   ;copy to EFLAGS
        pushfd                  ;push EFLAGS
        pop    eax              ;get new EFLAGS value
        xor    eax,ecx
        je     end_get_cpuid    ;if ID bit cannot be changed,

;CPU=Intel486 without CPUID
;instruction functionality

; Otherwise, execute CPUID instruction to determine vendor,
; family, model and stepping.

check_vendor:

        mov     [id_flag], 1            ; set flag for indicating use of
;CPUID inst
        mov     eax, 0                  ;set up for CPUID instruction
        cpuid
        mov     dword [vendor_id], ebx        ; Test for "GenuineIntel" vendor id.
        mov     dword [vendor_id+4], edx
        mov     dword [vendor_id+8], ecx
        mov     si, vendor_id
        mov     di, intel_id            ;RJK should be the length
        mov     cx, word [intel_id]

compare:
        repe cmpsb
        cmp     cx, 0                   ; must be a GenuineIntel if ecx =0
        jne     cpuid_data

intel_processor:
        mov [intel_proc], 1
        mov [intel-1], ' ' ; add a space so the Genuine Intel

; message prints out.

cpuid_data:
        mov     eax, 1
        cpuid
        mov     [saved_cpuid],eax       ;save for future use
        and     eax, 0F00H              ; mask everything but family
        shr     eax, 8
        mov     [cpu_type], al          ; set cpu_type with family

        mov     eax,saved_cpuid         ;restore data
        mov     [stepping], al
        and     [stepping], 0FH         ; isolate stepping info

        mov     eax, saved_cpuid
        mov     [themodel], al
        and     [themodel], 0F0H        ; isolate model info
        shr     [themodel], 4

end_get_cpuid:

        ret


;
; This procedure prints the appropriate cpuid string
; If the CPUID instruction was supported, it prints out
; the cpuid info.

print:
        push    ax bx cx dx

        cmp     [id_flag], 1            ; if set to 1, cpu supported CPUID
                                        ; instruction
                                        ; print detailed CPUID information
        je      print_cpuid_data

        mov     dx, id_msg
        mov     ah, 9h
        int     21h                     ; print initial message
        ret

print_86:
        cmp     [cpu_type], 0
        jne     print_286
        mov     dx, c8086
        mov     ah, 9h
        int     21h
        jmp     end_print

print_286:
        cmp     [cpu_type], 2
        jne     print_386
        mov     dx, c286
        mov     ah, 9h
        int     21h
        jmp     end_print


print_386:
        cmp     [cpu_type], 3
        jne     print_486
        mov     dx, c386
        mov     ah, 9h
        int     21h
        jmp     end_print


print_486:
        mov     dx, c486
        mov     ah, 9h
        int     21h
        jmp     end_print

print_cpuid_data:

        cmp     [cpu_type], 5
        jne     print_cpuid_cont

        mov     dx, Pentium
        mov     ah, 9
        int     21h

print_cpuid_cont:
        mov     dx, familymsg ;print family msg
        mov     ah, 9h
        int     21h
        mov     al, [cpu_type]
        mov     [dataCR], al
        add     [dataCR], 30H ; convert to ASCII
        mov     dx, dataCR ; print family info
        mov     ah, 9h
        int     21h

        mov     dx, steppingmsg ; print stepping msg
        mov     ah, 9h
        int     21h
        mov     al, [stepping]
        mov     [dataCR], al
        add     [dataCR], 30H ; convert to ASCII
        mov     dx, dataCR ; print stepping info
        mov     ah, 9h
        int     21h

        mov     dx, modelmsg ; print model msg
        mov     ah, 9h
        int     21h
        mov     al, [themodel]
        mov     [dataCR], al
        add     [dataCR], 30H ; convert to ASCII
        mov     dx, dataCR ; print stepping info
        mov     ah, 9h
        int     21h
end_print:
        pop     dx cx bx ax
        ret

; On com files place data under the code for COM files.
; ( or jump over the data at the start. Com files ever start from $100 )

saved_cpuid dd ?
vendor_id   rb 16
cpu_type    db ?
themodel    db ?
stepping    db ?
id_flag     db 0
intel_proc  db 0
id_msg      db "This system has a$"
c8086       db "n 8086/8088 microprocessor$"
c286        db "n Intel 286 microprocessor$"
c386        db "n Intel386 (TM) microprocessor$"
c486        db "n Intel486 (TM) DX microprocessor$"
Pentium     db " Pentium(TM) microprocessor", 13, 10, "$"
intel       db "This system contains a Genuine Intel Processor", 13, 10, "$"
modelmsg    db "Model: $"
steppingmsg db "Stepping: $"
familymsg   db "Processor Family: $"
period      db ".",13,10,"$"
dataCR      db ?,13,10,"$"
intel_id    db "GenuineIntel"
    
Post 24 Sep 2003, 06:29
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
robink



Joined: 17 Sep 2003
Posts: 14
robink 24 Sep 2003, 19:27
I am trying to learn assembly language AND move code from MASM and TASM to FASM all at the same time. Actually it is really helping me learn. I appreciate your help...

_________________
Thanks,

Robin
Post 24 Sep 2003, 19:27
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.