Author Topic: High Level Language in MASM  (Read 55972 times)

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #210 on: May 07, 2016, 10:29:07 PM »
Quote
why eax

Because eax is used as argument to the switch.

Quote
why 7E??

Because 7E is the maximum value in the switch (label$ + 2).
In the sample the value of label$ is 2:
Code: [Select]
.code
nop
nop
label$:

The minimum value is then 0 (label$ - 2) and the maximum value is 4 (label$ + 2).
Code: [Select]
00000012                        .switch eax
00000012                          .case label$ - 1 : mov al,1 : .endc
00000012  EB28              *   jmp @C0005
00000014                    *   @C0006:
00000014  B001              *   mov al,1
00000016                    *   .endc
00000016  EB35              *   jmp @C0007
00000018                          .case label$ - 2 : mov al,0 : .endc
00000018                    *   @C0008:
00000018  B000              *   mov al,0
0000001A                    *   .endc
0000001A  EB31              *   jmp @C0007
0000001C                          .case label$    : mov al,2 : .endc
0000001C                    *   @C0009:
0000001C  B002              *   mov al,2
0000001E                    *   .endc
0000001E  EB2D              *   jmp @C0007
00000020                          .case label$ + 1 : mov al,3 : .endc
00000020                    *   @C000A:
00000020  B003              *   mov al,3
00000022                    *   .endc
00000022  EB29              *   jmp @C0007
00000024                          .case label$ + 2 : mov al,4 : .endc
00000024                    *   @C000B:
00000024  B004              *   mov al,4
00000026                    *   .endc
00000026  EB25              *   jmp @C0007
00000028                        .endsw
00000028                    *   ALIGN 4
00000028                    *   @C000C:
00000028  00000000          *   dd @C0008
0000002C  00000000          *   dd @C0006
00000030  00000000          *   dd @C0009
00000034  00000000          *   dd @C000A
00000038  00000000          *   dd @C000B
0000003C                    *   @C0005:
0000003C  83F800            *   cmp eax,0
0000003F  7C0C              *   jl @C0007
00000041  83F804            *   cmp eax,4
00000044  7F07              *   jg @C0007
00000046  FF248500000000    *   jmp [@C000C+eax*4-(0*4)]
0000004D                    *   @C0007:

If you add code above label$, the value of label$ increases.
Code: [Select]
nop
nop
db 7Ah dup(0)
label$:
...
000000B8                    *   @C0005:
000000B8  83F87A     * cmp eax,122 ; 7A
000000BB  7C0C              *   jl @C0007
000000BD  83F87E     * cmp eax,126 ; 7E
000000C0  7F07              *   jg @C0007
000000C2  FF248518FEFFFF    *   jmp [@C000C+eax*4-(122*4)]
000000C9                    *   @C0007:

Quote
Switch (cases 7A..7E, 6 exits)

No, there is only 5: 7A, 7B, 7C, 7D, and 7E.

Note: EAX do not have a meaning in this case, so for a real test move EAX label$ + 1, or something in range.

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #211 on: May 07, 2016, 11:14:26 PM »
Here's a test case:
Code: [Select]
;
; build: asmc -pe switch.asm
;
    .486
    .model flat, c
    option casemap:none

option dllimport:<msvcrt>
printf proto :ptr byte, :vararg
exit proto :dword
option dllimport:NONE

.code
nop
nop
label$:

main proc
       
.switch eax
  .case 1 : mov al,1 ; warning A7008: .case without .endc: assumed fall through
  .case 2 : .endc
.endsw

.switch eax
  .case label$ - 1 : mov al,1 : .endc
  .case label$ - 2 : mov al,0 : .endc
  .case label$    : mov al,2 : .endc
  .case label$ + 1 : mov al,3 : .endc
  .case label$ + 2 : mov al,4 : .endc
.endsw

OPTION SWITCH: PASCAL
;
; should generate the same code (no warning)
;
mov edi,-1
xor esi,esi
.while sdword ptr edi < 7
db 4 dup(90h)
mov eax,edi
; int 3
.switch eax
  .case label$ - 1 : mov esi,1
  .case label$ - 2 : mov esi,0
  .case label$    : mov esi,2
  .case label$ + 1 : mov esi,3
  .case label$ + 2 : mov esi,4
.endsw
db 4 dup(90h)
printf( "EAX:%2i, ESI:%i\n", eax, esi )
inc edi
.endw

exit( 0 )
main endp

end main

Output:
Code: [Select]
EAX:-1, ESI:0
EAX: 0, ESI:0
EAX: 1, ESI:1
EAX: 2, ESI:2
EAX: 3, ESI:3
EAX: 4, ESI:4
EAX: 5, ESI:4
EAX: 6, ESI:4

If you insert the db 7Ah dup(0) above the label you get no match in the loop.
Code: [Select]
EAX:-1, ESI:0
EAX: 0, ESI:0
EAX: 1, ESI:0
EAX: 2, ESI:0
EAX: 3, ESI:0
EAX: 4, ESI:0
EAX: 5, ESI:0
EAX: 6, ESI:0

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #212 on: May 11, 2016, 06:19:44 AM »
I tested the Mirror$ macro and there was an error there (missing break statement in a switch apparently  :P).

Well, here’s the test used:
Code: [Select]
.486
.model flat, stdcall
.code

foo macro reg ; generate codes
bswap reg
exitm  <reg>
endm

bar macro const:req ; no code generated
local string
string equ <>
forc q, <const>
string catstr <q>, string
endm
exitm <string>
endm

ifdef __ASMC__
option asmc:on
endif
.while eax == bar("abc")
nop
.endw
.while foo(eax)
nop
.endw
.while foo(eax) || ecx == bar("123")
nop
.endw
.while eax == bar("abc") || edx == bar("cba") || ecx == bar("123")
nop
.endw
.while eax == bar("abc") || ( edx == bar("cba") && ecx == bar("123") )
nop
.endw
.while eax == bar("abc") && ( eax == bar("cba") || eax == bar("123") )
nop
.endw
.while foo(eax) || ( eax == bar("cba") && eax == bar("123") )
nop
.endw

END

The manual have some info on the switches and options added and changed. Masm style, including the JWasm file, but not in any way complete.

However the RTFM abbreviation may popup :lol:

jj2007

  • Member
  • *****
  • Posts: 7548
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #213 on: May 11, 2016, 09:29:37 AM »
I tested the Mirror$ macro and there was an error there (missing break statement in a switch apparently  :P).

What exactly is the problem? This snippet builds and runs just fine...

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  push Mirror$("em?")
  push Mirror$("robl")
  push Mirror$("he p")
  push Mirror$("'s t")
  push Mirror$("What")
  Inkey esp
EndOfCode

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #214 on: May 11, 2016, 11:01:28 AM »
It actually works very well now. I manage to circumvent the parsing problem but there is a special combination of conditions related to expansion of multiple macros. You mention some problem with the Mirror$ macro so this may be related to some test done earlier, but it has to be used in combination with .WHILE or .ELSEIF.

Here’s a crash test that illustrate the problem.

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #215 on: May 12, 2016, 05:02:56 AM »
The problem appears to be some old remains of the previous auto-off switch. By removing that it seems to work as expected.

It still rejects some macros but now on an individually basis as oppose to turning off the parsing. These macros were created for Masm anyway so no need for any special handling.

The generated code for FATAL.ASM:
Code: [Select]
; Disassembly of file: fatal.obj
; Wed May 11 20:39:22 2016
; Mode: 32 bits
; Syntax: MASM/ML
; Instruction set: 80386

.386
.model flat


_text   SEGMENT PARA PUBLIC 'CODE'                      ; section number 1

_text   LABEL NEAR
        jmp     ?_002                                   ; 0000 _ EB, 01

?_001:  nop                                             ; 0002 _ 90
?_002:  cmp     eax, 6513249                            ; 0003 _ 3D, 00636261
        jz      ?_001                                   ; 0008 _ 74, F8
        jmp     ?_004                                   ; 000A _ EB, 01

?_003:  nop                                             ; 000C _ 90
?_004:  bswap   eax                                     ; 000D _ 0F C8
        test    eax, eax                                ; 000F _ 85. C0
        jnz     ?_003                                   ; 0011 _ 75, F9
        cmp     ecx, 3355185                            ; 0013 _ 81. F9, 00333231
        jz      ?_003                                   ; 0019 _ 74, F1
        jmp     ?_006                                   ; 001B _ EB, 01

?_005:  nop                                             ; 001D _ 90
?_006:  bswap   eax                                     ; 001E _ 0F C8
        test    eax, eax                                ; 0020 _ 85. C0
        jnz     ?_005                                   ; 0022 _ 75, F9
        jmp     ?_008                                   ; 0024 _ EB, 01

?_007:  nop                                             ; 0026 _ 90
?_008:  cmp     eax, 6513249                            ; 0027 _ 3D, 00636261
        jz      ?_007                                   ; 002C _ 74, F8
        cmp     edx, 6382179                            ; 002E _ 81. FA, 00616263
        jz      ?_007                                   ; 0034 _ 74, F0
        cmp     ecx, 3355185                            ; 0036 _ 81. F9, 00333231
        jz      ?_007                                   ; 003C _ 74, E8
        jmp     ?_010                                   ; 003E _ EB, 01

?_009:  nop                                             ; 0040 _ 90
?_010:  cmp     eax, 6513249                            ; 0041 _ 3D, 00636261
        jz      ?_009                                   ; 0046 _ 74, F8
        cmp     edx, 6382179                            ; 0048 _ 81. FA, 00616263
        jnz     ?_011                                   ; 004E _ 75, 08
        cmp     ecx, 3355185                            ; 0050 _ 81. F9, 00333231
        jz      ?_009                                   ; 0056 _ 74, E8
?_011:  jmp     ?_013                                   ; 0058 _ EB, 01

?_012:  nop                                             ; 005A _ 90
?_013:  cmp     eax, 6513249                            ; 005B _ 3D, 00636261
        jnz     ?_014                                   ; 0060 _ 75, 0E
        cmp     eax, 6382179                            ; 0062 _ 3D, 00616263
        jz      ?_012                                   ; 0067 _ 74, F1
        cmp     eax, 3355185                            ; 0069 _ 3D, 00333231
        jz      ?_012                                   ; 006E _ 74, EA
?_014:  jmp     ?_016                                   ; 0070 _ EB, 01

?_015:  nop                                             ; 0072 _ 90
?_016:  bswap   eax                                     ; 0073 _ 0F C8
        test    eax, eax                                ; 0075 _ 85. C0
        jnz     ?_015                                   ; 0077 _ 75, F9
        cmp     eax, 6382179                            ; 0079 _ 3D, 00616263
        jnz     ?_017                                   ; 007E _ 75, 07
        cmp     eax, 3355185                            ; 0080 _ 3D, 00333231
; Note: Function does not end with ret or jmp
        jz      ?_015                                   ; 0085 _ 74, EB

_text   ENDS

_data   SEGMENT PARA PUBLIC 'DATA'                      ; section number 2

_data   ENDS

END

Code generated by Masm:
Code: [Select]
; Disassembly of file: fatal.obj
; Wed May 11 20:44:02 2016
; Mode: 32 bits
; Syntax: MASM/ML
; Instruction set: 80386

; Error: symbol names contain illegal characters,
; 1 Symbol names not changed

.386
.model flat

@comp.id equ 001220FCH                                  ; 1188092


_text   SEGMENT PARA PUBLIC 'CODE'                      ; section number 1

_text   LABEL NEAR
        jmp     ?_002                                   ; 0000 _ EB, 01

?_001:  nop                                             ; 0002 _ 90
?_002:  cmp     eax, 6513249                            ; 0003 _ 3D, 00636261
        jz      ?_001                                   ; 0008 _ 74, F8
        bswap   eax                                     ; 000A _ 0F C8
        jmp     ?_004                                   ; 000C _ EB, 01

?_003:  nop                                             ; 000E _ 90
?_004:  or      eax, eax                                ; 000F _ 0B. C0
        jnz     ?_003                                   ; 0011 _ 75, FB
        cmp     ecx, 3355185                            ; 0013 _ 81. F9, 00333231
        jz      ?_003                                   ; 0019 _ 74, F3
        bswap   eax                                     ; 001B _ 0F C8
        jmp     ?_006                                   ; 001D _ EB, 01

?_005:  nop                                             ; 001F _ 90
?_006:  or      eax, eax                                ; 0020 _ 0B. C0
        jnz     ?_005                                   ; 0022 _ 75, FB
        jmp     ?_008                                   ; 0024 _ EB, 01

?_007:  nop                                             ; 0026 _ 90
?_008:  cmp     eax, 6513249                            ; 0027 _ 3D, 00636261
        jz      ?_007                                   ; 002C _ 74, F8
        cmp     edx, 6382179                            ; 002E _ 81. FA, 00616263
        jz      ?_007                                   ; 0034 _ 74, F0
        cmp     ecx, 3355185                            ; 0036 _ 81. F9, 00333231
        jz      ?_007                                   ; 003C _ 74, E8
        jmp     ?_010                                   ; 003E _ EB, 01

?_009:  nop                                             ; 0040 _ 90
?_010:  cmp     eax, 6513249                            ; 0041 _ 3D, 00636261
        jz      ?_009                                   ; 0046 _ 74, F8
        cmp     edx, 6382179                            ; 0048 _ 81. FA, 00616263
        jnz     ?_011                                   ; 004E _ 75, 08
        cmp     ecx, 3355185                            ; 0050 _ 81. F9, 00333231
        jz      ?_009                                   ; 0056 _ 74, E8
?_011:  jmp     ?_013                                   ; 0058 _ EB, 01

?_012:  nop                                             ; 005A _ 90
?_013:  cmp     eax, 6513249                            ; 005B _ 3D, 00636261
        jnz     ?_014                                   ; 0060 _ 75, 0E
        cmp     eax, 6382179                            ; 0062 _ 3D, 00616263
        jz      ?_012                                   ; 0067 _ 74, F1
        cmp     eax, 3355185                            ; 0069 _ 3D, 00333231
        jz      ?_012                                   ; 006E _ 74, EA
?_014:  bswap   eax                                     ; 0070 _ 0F C8
        jmp     ?_016                                   ; 0072 _ EB, 01

?_015:  nop                                             ; 0074 _ 90
?_016:  or      eax, eax                                ; 0075 _ 0B. C0
        jnz     ?_015                                   ; 0077 _ 75, FB
        cmp     eax, 6382179                            ; 0079 _ 3D, 00616263
        jnz     ?_017                                   ; 007E _ 75, 07
        cmp     eax, 3355185                            ; 0080 _ 3D, 00333231
; Note: Function does not end with ret or jmp
        jz      ?_015                                   ; 0085 _ 74, ED

_text   ENDS

_data   SEGMENT PARA PUBLIC 'DATA'                      ; section number 2

        db      135 dup (?)                             ; 0000 _

_data   ENDS

END

jj2007

  • Member
  • *****
  • Posts: 7548
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #216 on: May 12, 2016, 04:12:38 PM »
Lines 4133 to 4146. Note that there is no error for line 4140. Apparently, if eax==Mirror$() is fine but .elseif chokes:
Code: [Select]
  .elseif eax==Mirror$(".hlp") || eax==Mirror$(".chm") || eax==Mirror$(".rtf") ;|| eax==Mirror$(".com")
push eax
mov ecx, selLen ; Len(selected text)
.if !eax
mov [edi], eax
.endif
pop eax
.if eax==Mirror$(".hlp") ; *** line 4140, OK *** ; eax=extension of help file
mov eax, HELP_PARTIALKEY ; gt127, so mov
.if ecx<3
m2m eax, HELP_INDEX ; not enough text selected, use index
.endif
invoke WinHelp, hWnd, esi, eax, edi ; edi points to current selected text
.elseif eax==Mirror$(".rtf") ; MasmBasic help

Code: [Select]
... (multiple line 4133 errors)
tmp_file.asm(4133) : error A2026: constant expected
 Mirror$(5)[MasmBasic.inc]: Macro called from
  tmp_file.asm(4133): Main line code
tmp_file.asm(4146) : error A2008: syntax error : typedef
 Mirror$(1)[MasmBasic.inc]: Macro called from
  tmp_file.asm(4146): Main line code
tmp_file.asm(4146) : error A2026: constant expected
 Mirror$(2)[MasmBasic.inc]: Macro called from
  tmp_file.asm(4146): Main line code
tmp_file.asm(4146) : error A2008: syntax error : typedef
 Mirror$(3)[MasmBasic.inc]: Macro called from
  tmp_file.asm(4146): Main line code
tmp_file.asm(4146) : error A2026: constant expected
 Mirror$(5)[MasmBasic.inc]: Macro called from
  tmp_file.asm(4146): Main line code
tmp_file.asm(7691) : error A2008: syntax error : typedef
 Mirror$(1)[MasmBasic.inc]: Macro called from
  tmp_file.asm(7691): Main line code
tmp_file.asm(7691) : error A2026: constant expected
 Mirror$(2)[MasmBasic.inc]: Macro called from
  tmp_file.asm(7691): Main line code
tmp_file.asm(7691) : error A2008: syntax error : typedef
 Mirror$(3)[MasmBasic.inc]: Macro called from
  tmp_file.asm(7691): Main line code
tmp_file.asm(7691) : error A2026: constant expected
 Mirror$(5)[MasmBasic.inc]: Macro called from
  tmp_file.asm(7691): Main line code

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #217 on: May 13, 2016, 04:23:48 AM »
I only used .WHILE in the test apparently and .ELSEIF needed some special handling.

Well, here’s a new test:
Code: [Select]
bar macro const:req
local string
string equ <>
forc q, <const>
string catstr <q>, string
endm
exitm <string>
endm

.while eax==bar(".hlp") || \
eax==bar(".chm") || \
eax==bar(".rtf") || \
eax==bar(".com")
nop
.endw

.if edx
nop
.elseif eax==bar(".hlp") || \
eax==bar(".chm") || \
eax==bar(".rtf") || \
eax==bar(".com")
nop
.endif


jj2007

  • Member
  • *****
  • Posts: 7548
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #218 on: May 13, 2016, 05:58:08 AM »
Well, here’s a new test:

No cigar yet :(

Doszip Macro Assembler Version 2.20
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.

 Assembling: tmp_file.asm
tmp_file.asm(4125) : error A2008: syntax error : typedef
 Mirror$(1)[MasmBasic.inc]: Macro called from

Code: [Select]
  .if cx=="sc" ; *.asc or *.qsc
call Snippet ; esi points to filename
  .elseif eax==Mirror$(".dll")

Btw versions 11.5. 20:27 and 12.5. 19:56 are both 2.20

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #219 on: May 13, 2016, 06:59:00 AM »
The macro seems to work as expected.
Code: [Select]
mtxt equ MIRROR$ ; chokes with JWasm <1.96
Mirror$ MACRO Src:REQ ;;usg: mirror text: cmp eax, Mirror$("Masm")
LOCAL hasQuotes, tmp$
  hasQuotes INSTR <Src>, <">
  ife hasQuotes
hasQuotes INSTR <Src>, <'>
  endif
  if hasQuotes
tmp$ equ <>
FORC char, <Src>
tmp$ CATSTR <char>, tmp$
ENDM
EXITM <tmp$>
  else
push Src
MbFlipP PROTO
call MbFlipP
EXITM emArr$ ; make sure Let reads it properly
  endif
ENDM

.if cx=="sc"
nop
.elseif eax==Mirror$(".dll")
nop
.elseif eax==mtxt(".dll")
nop
.endif

Output:
Code: [Select]
_text   LABEL NEAR
; Note: Length-changing prefix causes delay on Intel processors
        cmp     cx, 29539                               ; 0000 _ 66: 81. F9, 7363
        jnz     ?_001                                   ; 0005 _ 75, 03
        nop                                             ; 0007 _ 90
        jmp     ?_003                                   ; 0008 _ EB, 12

?_001:  cmp     eax, 1819042862                         ; 000A _ 3D, 6C6C642E
        jnz     ?_002                                   ; 000F _ 75, 03
        nop                                             ; 0011 _ 90
        jmp     ?_003                                   ; 0012 _ EB, 08

?_002:  cmp     eax, 1819042862                         ; 0014 _ 3D, 6C6C642E
        jnz     ?_003                                   ; 0019 _ 75, 01
        nop                                             ; 001B _ 90

Try using the /Xc switch to see if that works differently.

jj2007

  • Member
  • *****
  • Posts: 7548
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #220 on: May 13, 2016, 10:47:47 AM »
Try using the /Xc switch to see if that works differently.

That one works like a charm :t

So what is the difference?

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #221 on: May 14, 2016, 01:27:14 AM »
Quote
So what is the difference?
Delayed expansion of macros.

In Masm all macros are expanded in the pre-process part of the assembly and the expanded result used in the next stage. Asmc also expands in this process but delays some of the macros used in the HLL section.

In earlier versions of Asmc this was hacked by turning on the /Xc switch if the code became too complicated. Now this have been removed so it needs to handle the late-expansion correctly, hence the extensive testing.

Asmc have a Masm 8 compatible mode in the same way that Masm 8 has a Masm 5.10 compatible mode. The switch /Xc will the be equal the Masm switch /Zm.

/Zm Enable MASM 5.10 compatibility
/Xc Enable MASM 8.0 compatibility

That will be the same as JWasm 2.12:
/Xc Disable ASMC extensions

The problem at hand has to do with the local label counter that was incorrectly reset when the pre-processing was done. As an effect of the delayed expansion, in this case .ELSEIF, the first local in the Mirror$ macro, hasQuotes, was using the label ??0000. This happens to be a global label used by the macro ArgCount in WINDOWS.INC. The value of the label was typedef PROTO :DWORD, hence the typedef error in Mirror$.

So here’s a new test for the Mirror$ macro (whitout the /Xc switch)
Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc

.code

.if eax
.elseif eax==Mirror$(".dll")
.endif

END

jj2007

  • Member
  • *****
  • Posts: 7548
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #222 on: May 14, 2016, 02:55:13 AM »
Works fine :t

nidud

  • Member
  • *****
  • Posts: 1370
    • https://github.com/nidud/asmc
Re: High Level Language in MASM
« Reply #223 on: May 16, 2016, 10:09:29 PM »
The binaries of version 2.20 are now released to the SF site and I created an account at GitHub for the source code.

https://github.com/nidud/doszip

jj2007

  • Member
  • *****
  • Posts: 7548
  • Assembler is fun ;-)
    • MasmBasic
Re: High Level Language in MASM
« Reply #224 on: May 17, 2016, 12:51:52 AM »
The bin\asmc.exe in https://codeload.github.com/nidud/doszip/zip/master works like a charm 8)

Tested with RichMasm, the MasmBasic library and its testbed (770 lines). Build all timings for the latter:
Code: [Select]
  OxPT_Assembler  mlv615 ; 44.0kB, 1070 ms
  OxPT_Assembler  mlv10 ; 44.0kB, 1070 ms
  OxPT_Assembler  JWasm ; 44.0kB, 650 ms
  OxPT_Assembler  HJWasm ; 44.0kB, 940 ms
  OPT_Assembler  asmc ; 44.0kB, 480 ms

Over twice as fast as MASM - you can feel the difference: build all & run is practically immediate :t