Author Topic: Add instruction, data type and register names for automatically selected sizes  (Read 21710 times)

Offline ~

  • Jr. Member
  • *
  • Posts: 8
I see that the CPU is capable of automatically selecting the size of full sized machine words, instructions and registers.

But I also see that NASM lacks the capability to allow selecting automatically-sized code and data.

The assembly language that NASM supports should be extended for handling it. I've tested it with a macros file and existing code won't be affected. It's fully transparent as it's supposed to simply add the capability to use automatically-sized code and data.

The immediate result would be that it would be possible to write one single assembly source code version that could be directly recompiled for 16, 32 and 64-bit modes, as well as for standard 16-bit Unreal Mode, as long as automatically-mode-selecting instructions can be ported to all modes, which uses to be the case for user-level programs.

So I have created a macro file called "x86 Portable":
00000000__x86_Portable.asm

It allows support for things like:
Code: [Select]
;v2017-08-08

;;;;INIT: Documentation
;;;;INIT: Documentation
;;;;INIT: Documentation
;;;;INIT: Documentation
;;;;INIT: Documentation
;;;;INIT: Documentation
;;;;INIT: Documentation
;;;;INIT: Documentation


;Automatic size selection for data/variables:
;-------------------------------------------------------------------------
;wideword    -- Automatic size selection, 2, 4 or 8 bytes.
;ww          -- Automatic size selection, define wideword, 2, 4 or 8 bytes.
;wideword_SZ -- Automatic size selection, 2, 4 or 8 bytes.




;Automatic size selection for any on-stack call return addresses:
;-------------------------------------------------------------------------
;_CALL_STACK_ADDR_SZ_ -- 2, 4 or 8 bytes.




;Automatic size selection for CPU registers:
;-------------------------------------------------------------------------
;wideax -- 2, 4 or 8 bytes.
;widebx -- 2, 4 or 8 bytes.
;widecx -- 2, 4 or 8 bytes.
;widedx -- 2, 4 or 8 bytes.
;widesi -- 2, 4 or 8 bytes.
;widedi -- 2, 4 or 8 bytes.
;widesp -- 2, 4 or 8 bytes.
;widebp -- 2, 4 or 8 bytes.




;Automatic size selection for "Address" and "Operand" prefixes:
;-------------------------------------------------------------------------
;awide -- a16, a32 or nothing.
;owide -- a16, a32 or nothing.




;Automatic size selection for CPU instructions:
;-------------------------------------------------------------------------
;cmpswide -- 2, 4 or 8 bytes.
;lodswide -- 2, 4 or 8 bytes.
;stoswide -- 2, 4 or 8 bytes.
;movswide -- 2, 4 or 8 bytes.
;inswide  -- 2 or 4 bytes.
;outswide -- 2 or 4 bytes.
;retwide  -- 2, 4 or 8 byte POPs for return addresses.
;iretwide -- 2, 4 or 8 byte POPs for return addresses.



;Automatic variable or register selection for 64-bit CPU r8-r9 registers:
;-------------------------------------------------------------------------
;_r8  -- 2, 4 or 8 bytes.
;_r9  -- 2, 4 or 8 bytes.
;_r10 -- 2, 4 or 8 bytes.
;_r11 -- 2, 4 or 8 bytes.
;_r12 -- 2, 4 or 8 bytes.
;_r13 -- 2, 4 or 8 bytes.
;_r14 -- 2, 4 or 8 bytes.
;_r15 -- 2, 4 or 8 bytes.




;;;;END:  Documentation
;;;;END:  Documentation
;;;;END:  Documentation
;;;;END:  Documentation
;;;;END:  Documentation
;;;;END:  Documentation
;;;;END:  Documentation
;;;;END:  Documentation




;The reason why we don't use numbers like 8086 for 16-bit code
;and 386 for 32-bit code is that this source file is size-oriented
;and we want to indicate the actual machine word size, not just
;the base CPU.
;
;Indicating the CPU as a number might work and be better when we are
;dealing with CPU-oriented code. The fact of naming the CPUs with numbers
;was a very optimizing thinking from people at Intel, so CPUs can be
;directly identified and named in the CPU instructions themselves
;and in software by defining pure numbers.
;
;Set the default mode of x86 Portable to work under
;16-bit Unreal Mode (with access to 4 GB of address space):
;;
 %ifndef _x86_Portable__PLATFORMBITS_
  %ixdefine _x86_Portable__PLATFORMBITS_ 1632
 %endif


x86_Portable_START:

;Include a JMP instruction so that we can include this source file
;anywhere in a NASM/YASM assembly source code without causing failures
;due to the embedded data bytes here:
;;
 align 16
 jmp x86_Portable_END
 align 16

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%if _x86_Portable__PLATFORMBITS_==16     ;16-bit 8086 code

 %ixdefine _CALL_STACK_ADDR_SZ_ 2

 %ixdefine wideword    word
 %ixdefine ww          dw
 %ixdefine wideword_SZ 2
 %ixdefine wideword_SZ_BitRotationMultiply 1

 %ixdefine wideax    ax
 %ixdefine widecx    cx
 %ixdefine widedx    dx
 %ixdefine widebx    bx
 %ixdefine widesp    sp
 %ixdefine widebp    bp
 %ixdefine widesi    si
 %ixdefine widedi    di

 %ixdefine _r8       word[__r8]
 %ixdefine _r9       word[__r9]
 %ixdefine _r10      word[__r10]
 %ixdefine _r11      word[__r11]
 %ixdefine _r12      word[__r12]
 %ixdefine _r13      word[__r13]
 %ixdefine _r14      word[__r14]
 %ixdefine _r15      word[__r15]

 __r8  dw 0
 __r9  dw 0
 __r10 dw 0
 __r11 dw 0
 __r12 dw 0
 __r13 dw 0
 __r14 dw 0
 __r15 dw 0


 %ixdefine awide
 %ixdefine owide


 %ixdefine cmpswide  cmpsw
 %ixdefine lodswide  lodsw
 %ixdefine stoswide  stosw
 %ixdefine movswide  movsw
 %ixdefine inswide   insw
 %ixdefine outswide  outsw
 %ixdefine retwide   ret
 %ixdefine iretwide  iret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%elif _x86_Portable__PLATFORMBITS_==1632   ;16-bit Unreal Mode

 %ixdefine _CALL_STACK_ADDR_SZ_ 2

 %ixdefine wideword    dword
 %ixdefine ww          dd
 %ixdefine wideword_SZ 4
 %ixdefine wideword_SZ_BitRotationMultiply 2

 %ixdefine wideax    eax
 %ixdefine widecx    ecx
 %ixdefine widedx    edx
 %ixdefine widebx    ebx
 %ixdefine widesp    esp
 %ixdefine widebp    ebp
 %ixdefine widesi    esi
 %ixdefine widedi    edi

 %ixdefine _r8       dword[__r8]
 %ixdefine _r9       dword[__r9]
 %ixdefine _r10      dword[__r10]
 %ixdefine _r11      dword[__r11]
 %ixdefine _r12      dword[__r12]
 %ixdefine _r13      dword[__r13]
 %ixdefine _r14      dword[__r14]
 %ixdefine _r15      dword[__r15]

 __r8  dd 0
 __r9  dd 0
 __r10 dd 0
 __r11 dd 0
 __r12 dd 0
 __r13 dd 0
 __r14 dd 0
 __r15 dd 0


 %ixdefine awide     a32
 %ixdefine owide     o32


 %ixdefine cmpswide  cmpsd
 %ixdefine lodswide  lodsd
 %ixdefine stoswide  stosd
 %ixdefine movswide  movsd
 %ixdefine inswide   insd
 %ixdefine outswide  outsd
 %ixdefine retwide   ret
 %ixdefine iretwide  iret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%elif _x86_Portable__PLATFORMBITS_==32    ;32 bit x86 Protected Mode code

 %ixdefine _CALL_STACK_ADDR_SZ_ 4

 %ixdefine wideword    dword
 %ixdefine ww          dd
 %ixdefine wideword_SZ 4
 %ixdefine wideword_SZ_BitRotationMultiply 2

 %ixdefine wideax    eax
 %ixdefine widecx    ecx
 %ixdefine widedx    edx
 %ixdefine widebx    ebx
 %ixdefine widesp    esp
 %ixdefine widebp    ebp
 %ixdefine widesi    esi
 %ixdefine widedi    edi

 %ixdefine _r8       dword[__r8]
 %ixdefine _r9       dword[__r9]
 %ixdefine _r10      dword[__r10]
 %ixdefine _r11      dword[__r11]
 %ixdefine _r12      dword[__r12]
 %ixdefine _r13      dword[__r13]
 %ixdefine _r14      dword[__r14]
 %ixdefine _r15      dword[__r15]

 __r8  dd 0
 __r9  dd 0
 __r10 dd 0
 __r11 dd 0
 __r12 dd 0
 __r13 dd 0
 __r14 dd 0
 __r15 dd 0


 %ixdefine awide
 %ixdefine owide


 %ixdefine cmpswide  cmpsd
 %ixdefine lodswide  lodsd
 %ixdefine stoswide  stosd
 %ixdefine movswide  movsd
 %ixdefine inswide   insd
 %ixdefine outswide  outsd
 %ixdefine retwide   ret
 %ixdefine iretwide  iret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%elif _x86_Portable__PLATFORMBITS_==64       ;64-bit Long Mode code

 %ixdefine _CALL_STACK_ADDR_SZ_ 8

 %ixdefine wideword    qword
 %ixdefine ww          dq
 %ixdefine wideword_SZ 8
 %ixdefine wideword_SZ_BitRotationMultiply 3

 %ixdefine wideax    rax
 %ixdefine widecx    rcx
 %ixdefine widedx    rdx
 %ixdefine widebx    rbx
 %ixdefine widesp    rsp
 %ixdefine widebp    rbp
 %ixdefine widesi    rsi
 %ixdefine widedi    rdi

 %ixdefine _r8       r8
 %ixdefine _r9       r9
 %ixdefine _r10      r10
 %ixdefine _r11      r11
 %ixdefine _r12      r12
 %ixdefine _r13      r13
 %ixdefine _r14      r14
 %ixdefine _r15      r15


 %ixdefine awide
 %ixdefine owide


 %ixdefine cmpswide  cmpsq
 %ixdefine lodswide  lodsq
 %ixdefine stoswide  stosq
 %ixdefine movswide  movsq
 %ixdefine inswide   insd
 %ixdefine outswide  outsd
 %ixdefine retwide   retq
 %ixdefine iretwide  iretq



%endif



align 16
x86_Portable_END:




;EOF

r8 to r15 are defined as WIDEWORDs if the current CPU mode doesn't have those Long Mode registers.

I will post examples of what can be done with it here later, I already have them as working code.

A macros file like this works great, but adding it to NASM itself would turn x86 Intel sytax assembly language into a low level language with nearly the same degree of code portability and reusability than C. I've proven it to myself. This is all NASM and Intel syntax x86 assembly language need to have added to improve them considerably.
« Last Edit: August 10, 2017, 05:20:24 PM by ~ »

Offline ~

  • Jr. Member
  • *
  • Posts: 8
Here I have a set of programs to enter Unreal Mode and Protected Mode.

I'm gradually replacing code that uses fixed-sized assembly variables and CPU registers by the variety shown here, like wideword and wideax, which will allow me to reuse the code and generate it properly for 16, 32 and 64-bit modes:

Source code:
BOOTCFG__v2017-06-16.zip

Project information:
http://devel.archefire.org/forum/viewtopic.php?t=2274&hl=en
« Last Edit: August 10, 2017, 05:21:07 PM by ~ »