Assembler insert strange instructions [At end of topic new question VESA BIOS]

Started by kyoto008, December 13, 2013, 09:34:32 PM

Previous topic - Next topic

kyoto008

Why assembler insert some strange instructions at my code?
I written some code for meet requirements registers preservation for some third party boot loader kernel system On Time RTOS-32. You can see requirements at url at code for MASM32 below. Need MZ-file. Code will run at x86 16bit real segmented mode at modern CPUs. I try use MASM32 and fasm. Both insert nearly same strange instructions at my code, that I not written there. Why is this happened?
My code:

    ;See table with columns "Register Contains Preserve" at and of document:
    ; http://www.on-time.com/rtos-32-docs/rttarget-32/programming-manual/rtloc/initializing-target-hardware/initcode.htm
    ;assembler commandline:
    ;   ml /c f.asm
    ;   link16 f
    .686
    .model tiny
    ASSUME SS:NOTHING, DS:NOTHING, CS:ERROR, ES:ERROR, GS:ERROR, FS:ERROR
    .code; code segment
    main:;entry point to program
    jmp cseg; jump to code get over data
    ; global variables:
    ss_ dd ?
    esp_ dd ?
    ;stack:
    stack_reserved db 60 dup (?)
    stacktop dd ?
    ;save register for meet requirements RTOS and
    ;intialize registers for work:
    cseg:
    mov eax, cs
    mov edx, ds;ds saved at edx. edx and eax not preserved, because needn't.
    mov ds, eax
    mov eax, ss
    mov ss_, eax
    mov eax, esp
    mov esp_, eax
    mov eax, ds
    mov ss, eax
    mov esp, DWORD PTR stacktop
    pushfd
    pushad
    mov eax, es
    push eax;
    mov eax, fs
    push eax;
    mov eax, gs
    push eax;
    ;do work:
    ;...
    ;do some work. omit it.
    ;...
    ;restore preserved registers:
    pop eax
    mov gs, eax
    pop eax
    mov fs, eax
    pop eax
    mov es, eax
    popad
    popfd
    mov eax, esp_
    mov esp, eax
    mov eax, ss_
    mov ss, eax
    mov ds, edx
    jmp ebx;return to near absolute address
    end main


I use hiew disassembler (and debug.com and debugx.com) for see output of assembler.
Also I try trace at debugx.com. That strange instructions realy executed. It is not disassembler's decode error (if debugx not have emulator for trace).
disassembler result at hiew:

    00000200: EB48                           jmps        00000024A
    ;it is ok. it data segment with zero initialized.
    00000202: 0000                           add         [bx][si],al
    00000204: 0000                           add         [bx][si],al
    ...
    00000246: 0000                           add         [bx][si],al
    00000248: 0000                           add         [bx][si],al
    0000024A: 8CC8                           mov         ax,cs
    0000024C: 8CDA                           mov         dx,ds
    0000024E: 8ED8                           mov         ds,ax
    00000250: 8CD0                           mov         ax,ss
    00000252: 2EA30200                       mov         cs:[00002],ax
    ;what is happened? add ... [si]...? I not written it.
    00000256: 0000                           add         [bx][si],al
    00000258: 8BC4                           mov         ax,sp
    0000025A: 2EA30600                       mov         cs:[00006],ax
    ;same
    0000025E: 0000                           add         [bx][si],al
    00000260: 8CD8                           mov         ax,ds
    00000262: 8ED0                           mov         ss,ax
    ;same oh ... five lines...
    00000264: 2E8B25                         mov         sp,cs:[di]
    00000267: 46                             inc         si
    00000268: 0000                           add         [bx][si],al
    0000026A: 009C608C                       add         [si][-073A0],bl
    0000026E: C0508CE0                       rcl         b,[bx][si][-074],0E0 ;'р'
    ;why all it is happened?
    00000272: 50                             push        ax
    00000273: 8CE8                           mov         ax,gs
    00000275: 50                             push        ax
    00000276: 58                             pop         ax
    00000277: 8EE8                           mov         gs,ax
    00000279: 58                             pop         ax
    0000027A: 8EE0                           mov         fs,ax
    0000027C: 58                             pop         ax
    0000027D: 8EC0                           mov         es,ax
    0000027F: 61                             popa
    00000280: 9D                             popf
    00000281: 2EA10600                       mov         ax,cs:[00006]
    00000285: 0000                           add         [bx][si],al
    00000287: 8BE0                           mov         sp,ax
    00000289: 2EA10200                       mov         ax,cs:[00002]
    0000028D: 0000                           add         [bx][si],al
    0000028F: 8ED0                           mov         ss,ax
    00000291: 8EDA                           mov         ds,dx
    00000293: FFE3                           jmp         bx


How I can fix it?

jj2007

Try another debugger. Debuggers are often confused about strange mixes of 16- and 32-bit code ;-)

And welcome to the forum :icon14:

dedndave

    00000252: 2EA30200                       mov         cs:[00002],ax
    00000256: 0000                           add         [bx][si],al


is actually

    00000252: 2EA302000000                   mov         cs:[000000002],ax

but - you want to write code for 16-bit real mode
it thinks you are writing to a 32-bit address

this doesn't seem right - comment it out to see what happens

;    ASSUME SS:NOTHING, DS:NOTHING, CS:ERROR, ES:ERROR, GS:ERROR, FS:ERROR

this doesn't seem valid, either

    mov eax, ss

japheth

Quote from: kyoto008 on December 13, 2013, 09:34:32 PM
How I can fix it?

You have to modify your code like this:


    .model tiny
    .686


That is, first the .model directive and the cpu directive line behind .model.

It's because the assembler, when it encounters the .model directive, determines the default segment size based on the current cpu setting. And you want your segments to be 16-bit.

kyoto008

Quote from: jj2007 on December 13, 2013, 10:07:32 PM
Try another debugger
I will try it.

Quote
And welcome to the forum :icon14:
A big thanks, peoples.  ::)

Quote from: dedndave on December 13, 2013, 10:23:09 PM
but - you want to write code for 16-bit real mode
it thinks you are writing to a 32-bit address
this doesn't seem right - comment it out to see what happens
How I can change 32bit mode of assembler masm32 to 16bit? Need I will swap directivities .model tiny and .686, same as answered below?

Quote
    mov eax, ss
Should I will remove e-prefix at register name eax, e.g. ax? I not want remove e-prefix at register mnemonic name. I want preserve all used registers with full size 32bit, not with - 16bit. Preserve registers at program's begin and restore at end of program. It's may be not required, but I want it for safety. Is you see another error at this command? For example, is it command not combined correctly with my ASSUME settings?

Quote
;    ASSUME SS:NOTHING, DS:NOTHING, CS:ERROR, ES:ERROR, GS:ERROR, FS:ERROR
this doesn't seem valid
I unknown name directive for .code segment at assembler masm32. I wanted write ASSUME SS:CODE, DS:CODE, CS:CODE, ES:ERROR, GS:ERROR, FS:ERROR, but I short handed. I think directive ASSUME assign default segment prefix for CPU instructions and operands at instruction able not fully qualified.

dedndave

Japheth is correct - he's pretty sharp - lol
i forgot about the .MODEL behaviour, because i use code templates   :P
then, you can remove the comment on ASSUME

the segment registers are always 16 bits wide, whether you are writing 16-bit or 32-bit code

kyoto008

Thanks to all. Bugs was corrected.
Correct version of code:
;See table with columns "Register Contains Preserve" at and of document:
;http://www.on-time.com/rtos-32-docs/rttarget-32/programming-manual/rtloc/initializing-target-hardware/initcode.htm
.model tiny
.686
.code; code segment
main:;entry point to program
jmp cseg; jump to code get over data
; global variables:
STACKSIZE EQU 0076h
ss_ dd ?
esp_ dd ?
;stack:
stack_reserved db STACKSIZE dup (?)
stacktop:
;save register for meet requirements RTOS and
;intialize registers for work:
cseg:
mov eax, cs
mov edx, ds; ds saved at edx. edx and eax not preserved, because not required.
mov ds, eax
mov eax, ss
mov ss_, eax
mov eax, esp
mov esp_, eax
mov eax, ds
mov ss, eax
mov eax, stacktop
mov esp, eax
pushad
mov eax, es
push eax
mov eax, fs
push eax
mov eax, gs
push eax
mov eax, ds
mov es, eax
;do work:
;...
;do some work.
;...
;restore preserved registers:
pop eax
mov gs, eax
pop eax
mov fs, eax
pop eax
mov es, eax
popad
mov eax, esp_
mov esp, eax
mov eax, ss_
mov ss, eax
mov ds, edx

;jmp ebx;return to near absolute address
end main

Change "mov esp, DWORD PTR stacktop" to "mov eax, stacktop". It's my bug.
Remove pushfd\popfd. Why it helped me? Boot system at my VMWare virtual machine has gone to reboot before this instructions removed.


______
Other complex question for topic reuse:
I want initialize Flat Panel Display at boot loader at real CPU mode before kernel On Time RTOS-32 gone to virtual protected CPU mode.
I want use VESA BIOS Extension/ Flat Panel Interface (VBE/FP).
http://www.codon.org.uk/~mjg59/tmp/VBEFP_32.PDF
Is it actualy BIOS service and can be supported on my machine?
I use HSD100IFW1_F01 LVDS display with SOM-7562 B1 embeded system with Intel N455 and ICH8M (82801HBM).
http://www.anewtech.net/pdf/Anewtech-AD-SOM-7562-B1.pdf

MichaelW

Running under Windows XP on a Dell system from ~2003 that shipped with a FP display, if I use the Run command to start Debug, enter assembly mode, and key in the following code:

mov ax, 4F11
mov bx, 0
mov di, 200
int 10


Then exit assembly mode and use the Proceed command (P) to execute everything through the interrupt call, I get AX = 014F, and according to the PDF under VBE/FP Completion Codes:

VBE RETURN STATUS
AL == 4Fh: Function is supported
AL != 4Fh: Function is not supported
AH ==00h: Function call successful
AH ==01h: Function call failed
AH ==02h: Function is not supported in the current hardware configuration
AH ==03h: Function call invalid in current video mode


This means that the function is supported, but that it failed. The system originally had a 17" FP with a VGA connection IIRC, but now has a ~2-year old 27" wide screen display with a DVI connection, and this could be the reason the function failed.
Well Microsoft, here's another nice mess you've gotten us into.

dedndave

i tried it under SymDeb...
the first time, it returned 0 in AX
ran it again, it went full-screen and returned 4F11h in AX   :redface:

oh - that's under XP MCE2005 SP3

Antariy

Entered and proceed in debug - code goes full screen, AX is zero. XPSP2 is the OS.

kyoto008

Quote from: MichaelW on December 14, 2013, 11:28:16 PMRunning under Windows XP on a Dell system
Quote from: dedndave on December 15, 2013, 02:37:01 AMi tried it under SymDeb...
VBE/FP and all BIOS entry points from interrupt 10h shouldn't work on virtual or protected mode CPU under Windows or Linux. I plan to use my above code to run screen initialization code through VBE/FP on real mode CPU boot loader before switch to protected mode. Real mode CPU can be obtained for any peoples by running in DOS without memory extenders emm386.sys or himem.sys.

MichaelW

Quote from: kyoto008 on December 15, 2013, 05:43:58 AM
VBE/FP and all BIOS entry points from interrupt 10h shouldn't work on virtual or protected mode CPU under Windows or Linux. I plan to use my above code to run screen initialization code through VBE/FP on real mode CPU boot loader before switch to protected mode. Real mode CPU can be obtained for any peoples by running in DOS without memory extenders emm386.sys or himem.sys.

For Windows XP 16-bit apps run under NTVDM, and while NTVDM will block some of the BIOS functions, for example those that do low-level access to a hard disk, it will allow most of them to work, more or less.

Well Microsoft, here's another nice mess you've gotten us into.

kyoto008

Quote from: MichaelW on December 15, 2013, 09:19:53 AM
For Windows XP 16-bit apps run under NTVDM, and while NTVDM will block some of the BIOS functions, for example those that do low-level access to a hard disk, it will allow most of them to work, more or less.
NTVDM not use BIOS. NTVDM translate all BIOS functions calls to system drivers.

MichaelW

Quote from: kyoto008 on December 15, 2013, 10:09:09 AM
NTVDM not use BIOS. NTVDM translate all BIOS functions calls to system drivers.

I have no way to monitor any of that so I can't know how it works at a low level. Most BIOS functions will work under NTVDM, more or less. I added the more or less qualification because some of them do not work the same way as they do in RM, counters tend to run faster than normal, the BIOS "sees" serial and parallel ports that do not exist in the hardware, etc. It's not an ideal way to run RM code, but it's generally workable for a quick test, which is what I used it for. I was not trying to start an argument I was trying to help you.

Well Microsoft, here's another nice mess you've gotten us into.

kyoto008