News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Reg16 or reg32??

Started by jj2007, September 05, 2013, 04:04:55 AM

Previous topic - Next topic

Antariy

Quote from: MichaelW on September 05, 2013, 01:11:55 PM
Quote from: Antariy on September 05, 2013, 10:11:18 AM
DEBUG is aware only about 8086 instruction set.

Which DEBUG?

http://www.japheth.de/debxxf.html

No, I meant the "standard" DEBUG coming with DOS/Windows

Antariy

Contrary example: many disassemblers will "flawlessly" disassembly next piece, but without opcodes field you will not find why original program crashed

include \masm32\include\masm32rt.inc

.code
option prologue:none
option epilogue:none

printit proc    dwVal
    invoke crt_printf,CTXT("printit: %p",13,10),dword ptr [esp+4]
    db 66h
    ret 4
printit endp

start:

invoke printit,12345678h
invoke crt_printf,CTXT("RET LOL")

end start

jj2007

Olly gives you a comment at least...

00401012       À.  66:C2 0400          retn 4                                 ; 16-bit return

Antariy

Quote from: jj2007 on September 05, 2013, 09:08:54 PM
Olly gives you a comment at least...

00401012       À.  66:C2 0400          retn 4                                 ; 16-bit return


Yes, I know. But statical disassembly analysis will not show it... if the disassembler doesn't track such things like Olly does or it doesn't show opcodes field. Though, all disassemblers do this, so, this is just a "fun" example :biggrin:
The interesting point is this kind of return works with IP and not with EIP - even though there's no "directly accessed" instruction pointer regester. The same it will do in 16 bit mode - work with EIP instead of IP.

Gunther

Alex,

Quote from: Antariy on September 06, 2013, 12:00:52 AM
The interesting point is this kind of return works with IP and not with EIP - even though there's no "directly accessed" instruction pointer regester. The same it will do in 16 bit mode - work with EIP instead of IP.

This is a matter of course; we're speaking about DOS (Real Mode or V86 Mode). The things are different for 32 bit DPMI clients. But that's another story.

Gunther
You have to know the facts before you can distort them.

Antariy

Quote from: Gunther on September 06, 2013, 02:42:42 AM
Alex,

Quote from: Antariy on September 06, 2013, 12:00:52 AM
The interesting point is this kind of return works with IP and not with EIP - even though there's no "directly accessed" instruction pointer regester. The same it will do in 16 bit mode - work with EIP instead of IP.

This is a matter of course; we're speaking about DOS (Real Mode or V86 Mode). The things are different for 32 bit DPMI clients. But that's another story.

Gunther

Yes, tryings to set EIP in not-DPMI mode are fault.

Gunther

Hi Alex,

Quote from: Antariy on September 06, 2013, 01:00:39 PM
Yes, tryings to set EIP in not-DPMI mode are fault.

it's not only for DPMI clients. If the basis of Protected Mode is VCPI, XMS or RAW, we would have the same effects. It's simply a question of the segment size: 16 bit segments need IP while 32-bit segments need EIP.

Gunther
You have to know the facts before you can distort them.

japheth

I'm a nitpicker, so I'll have to slightly correct some of the previous statements  :icon_mrgreen:

You can use 32-bit CALLs and RETs in 16-bit code segments and the opposite, using 16-bit CALLs and RETs in 32-bit, is also possible.

Here's a sample of a 16-bit code, calling a procedure with 32-bit call/ret:


.286
.model small
.dosseg
.stack 400h
.386

.code

msg1 db "abc$"

p1:
mov ah,9
mov dx,offset msg1
int 21h
;; retd    ;!!!
        db 66h
        ret

start:
push cs
pop ds
call near32 ptr p1    ;!!!
mov ah,4ch
int 21h

end start


And a 32-bit DPMI sample, using 16-bit call/ret:


;--- DPMICL32.ASM: 32bit DPMI application written in MASM syntax.
;--- assemble: JWasm -mz dpmicl32.asm

LF  equ 10
CR  equ 13

    .386
    .model small

    .dosseg     ;this ensures that stack segment is last

    .stack 1024

    .data

szWelcome db "welcome in protected-mode",CR,LF,0

    .code

start:
    mov esi, offset szWelcome
    call near16 ptr printstring         ;!!!
    mov ax, 4C00h   ;normal client exit
    int 21h

;--- print a string in protected-mode with simple
;--- DOS commands not using pointers.

printstring:
    lodsb
    and al,al
    jz stringdone
    mov dl,al
    mov ah,2
    int 21h
    jmp printstring
stringdone:
;;    retw    ;!!!
    db 66h
    ret

;--- now comes the 16bit initialization part

_TEXT16 segment use16 word public 'CODE'

start16:
    mov ax,ss
    mov cx,es
    sub ax, cx
    mov bx, sp
    shr bx, 4
    inc bx
    add bx, ax
    mov ah, 4Ah     ;free unused memory
    int 21h

    mov ax, 1687h   ;DPMI host installed?
    int 2Fh
    and ax, ax
    jnz nohost
    push es         ;save DPMI entry address
    push di
    and si, si      ;requires host client-specific DOS memory?
    jz nomemneeded
    mov bx, si
    mov ah, 48h     ;alloc DOS memory
    int 21h
    jc nomem
    mov es, ax
nomemneeded:
    mov ax, DGROUP
    mov ds, ax
    mov bp, sp
    mov ax, 0001        ;start a 32-bit client
    call far ptr [bp]   ;initial switch to protected-mode
    jc initfailed

;--- now in protected-mode

;--- create a 32bit code selector and jump to 32bit code

    mov cx,1
    mov ax,0
    int 31h
    mov bx,ax
    mov cx,_TEXT
    mov dx,cx
    shl dx,4
    shr cx,12
    mov ax,7
    int 31h     ;set base address
    mov dx,-1
    mov cx,0
    mov ax,8
    int 31h     ;set descriptor limit to 64 kB
    mov cx,cs
    lar cx,cx
    shr cx,8
    or ch,40h
    mov ax,9
    int 31h     ;set code descriptors attributes to 32bit
    push ebx
    push offset start
    retd        ;jump to 32-bit code

nohost:
    mov dx, offset dErr1
    jmp error
nomem:
    mov dx, offset dErr2
    jmp error
initfailed:
    mov dx, offset dErr3
error:
    push cs
    pop ds
    mov ah, 9
    int 21h
    mov ax, 4C00h
    int 21h

dErr1 db "no DPMI host installed",CR,LF,'$'
dErr2 db "not enough DOS memory for initialisation",CR,LF,'$'
dErr3 db "DPMI initialisation failed",CR,LF,'$'

_TEXT16 ends

    end start16


See the near16 and near32 overrides for the call instructions; also retw and retd are used here, to avoid using the ugly DB directive to add size prefixes. This syntax is supported by masm and jwasm.

But the limitations for 16-bit are still true, of course: the value of EIP must remain < 0x10000.

EDIT: RETW/RETD apparently always create a FAR return, so you'll have to use DB instead.

Gunther

Andreas,

Quote from: japheth on September 07, 2013, 05:02:17 PM
I'm a nitpicker, so I'll have to slightly correct some of the previous statements  :icon_mrgreen:

You can use 32-bit CALLs and RETs in 16-bit code segments and the opposite, using 16-bit CALLs and RETs in 32-bit, is also possible.

sure, no question. But don't forget the 66h prefix byte. That was my point.

Gunther
You have to know the facts before you can distort them.

Antariy

Quote from: japheth on September 07, 2013, 05:02:17 PM
Here's a sample of a 16-bit code, calling a procedure with 32-bit call/ret:

Far call and return will work, too, while CS and EIP value are both DWORDs values in the stack, and EIP is in 16 bit range.

16 bit call/ret in 32 bit mode is possible when the "guard area" <10000h is commited and is executable (since the CALL/RET itself doesn't change anything with the segmentation (until it's not FAR) - 16 bit CALL/RET in 32 bit code still remain the code 32 bit, the point of my #16 post was that operand size override prefix "plays" with (E)IP size, not the modes (16/32 bit), so, in "usual program" 16 bit return in the program will cause a crash, since the area of return is not commited)

Quote from: japheth on September 07, 2013, 05:02:17 PM
But the limitations for 16-bit are still true, of course: the value of EIP must remain < 0x10000.

That's what I meant here

Quote from: Antariy on September 06, 2013, 01:00:39 PM
Yes, tryings to set EIP in not-DPMI mode are fault.


But probably the fault was posting some funny stuff in the reply 16 without millions of reservations ::)

Antariy

Quote from: japheth on September 07, 2013, 05:02:17 PM
I'm a nitpicker, so I'll have to slightly correct some of the previous statements  :icon_mrgreen:

Anyway your input was like a synopsis on the topic :t

Gunther

Quote from: Antariy on September 07, 2013, 08:14:32 PM
Anyway your input was like a synopsis on the topic :t

good synopsis and by the way it has not much to do with Korinthenkackerei.

Gunther

You have to know the facts before you can distort them.

Antariy

Hi Gunther :biggrin:

Quote from: Gunther on September 07, 2013, 08:54:09 PM
Korinthenkackerei.

May you explain what means this word?

nidud

#28
deleted

Gunther

Hi Alex,

Quote from: Antariy on September 07, 2013, 09:54:28 PM
Hi Gunther :biggrin:

Quote from: Gunther on September 07, 2013, 08:54:09 PM
Korinthenkackerei.

May you explain what means this word?

of course. It's the German translation of nitpcker or also nit-picker. One can translate it as:

Korinthenkacker or Krümelkacker or Erbsenzähler or Beckmesser. See also: that description.

Sinsi,

Quote from: nidud on September 07, 2013, 10:50:51 PM
Sorry, I'm a nitpicker too  :lol:

A nit is a louse (laus) egg (eizelle)
Korinthe – Corinthian, piching grapes; dehydrated: currant (a raisin)

Since a grape is somewhere between a "kokosnuss" and a nit
a more correct word should then be Lauseizellekackerei

The trick is that you can't translate some phrases one to one (see my description above).

Gunther
You have to know the facts before you can distort them.