Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NDISASM : Disassembly shows different instructions!!

237 views
Skip to first unread message

Anish

unread,
Jun 17, 2004, 3:48:32 AM6/17/04
to
Hi all,

i have written a protected mode code in x86 assembly. I use NASM 0.98
on LINUX 2.4.22.
i'm assembling like nasm -f elf <XXX.asm>
using linker to generate bin out of it....
My problem is i always see change in few instructions after
disassembly of the code.
For Eg: jmp 0x10:CATCHME
here after using ndisasm, i see jmp 0x0:CATCHME.
one more instance is lgdt [lgdt_desc]
call init_idt
here after using ndisasm, i can't see call instruction at all. i had
to insert 2 or 3 NOP instructions to see call init_idt.

i want to know is it b'coz of previous instruction size or
disassembly issue. Pls anybody if they have experienced let me know.
i can't see the amount of NOP instruction lying there doing nothin...i
want to exclude and make the code more readable.........

Thanx,
Anish

Frank Kotler

unread,
Jun 17, 2004, 5:41:33 AM6/17/04
to

Hi Anish,

These instructions disassemble okay for me. There's a known issue with
SSE2 instructions, and the "autosynch" feature has never done anything
useful, that I've noticed, but it should handle this, I think...

One thing that occurs to me is that if you're using 0.98, you may not
have any documentation for ndisasm. *That* would make things pretty
cryptic! "ndisasm.doc" was distributed up to about 0.96, but kinda got
lost in 0.97 and 0.98. To make sure it doesn't happen again, it's now an
appendix to the main Nasm manual (...making it even *more* bloated...)

http://nasm.sourceforge.net/doc/html/nasmdoca.html

You'll need to indicate 32-bits ("misdisassembling" 16/32 bits gives
wildly wrong results!) - probably an origin, and an initial synch point,
or "-e" to skip over a header(?) to get an intelligent disassembly. The
only way I've found to disassemble mixed 16/32 bit code is to do it
twice, once with "-b16" and once with "-b32", and cut-and-paste the
results - there's no way to get ndisasm to switch in midstream, I don't
think. You won't run into that with "-f elf" anyway, I guess...

If you can't get it right with some tweaking of the command line, post
again. You might want "nop"s in your code for speed/alignment reasons,
but I agree you don't want 'em just so ndisasm will work!

Best,
Frank

Anish

unread,
Jun 23, 2004, 3:09:40 AM6/23/04
to
Hi Frank,

Thanx for your suggestion. i visited that website, but i couldn't find
much information.

Let me explain the problem completely i'm currently facing. I am
unable to switch to protected mode. Jmp after PE bit set in CR0 is
rebooting the machine.
i would like to know the faulty code if any in the program.
I really reached my patience limit as i have been debugging this from
past 1 week.

I am attaching my code. Can anybody figure out what's wrong with this
code.
3 codes have been attached.

BOOT LOader loads Setup and Protected Code at 0x00007e00 and
0x00001000 respectively.

Bootloader ===> jumps to ====> 0x07e00:0000 ( setup Code )
Setup COde ===> Jumps to ====> 0x10:0x00001000 ( Protected Mode Code )

Setup code does GDT Initialization and switches to protected mode.
One more thing i'm using script file to link. here is the procedure.

For SetupCode:
nasm -f elf setupcode
ld setupcode.o -o setupcode.bin --script <....>
/*************Linker Script ***********/
OUTPUT_FORMAT("binary")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0x7e00;
_text = .; /*start of Text section */
.text :
{
*(.text)
}
_etext = .;

.data : { *(.data) }
_edata = .;
}
/*********End of Linker Script ****************/

For ProtectedCode:
nasm -f elf protectcode
ld protectcode.o -o protectcode.bin --script <....>
/*************Linker Script ***********/
Same as above but starting address is . = 0x00001000
/************* End of Linker script **********/

Inside the FLOPPY:
BootLoader in Sector 0
Setup COde in Sector 1 to 17
Protected Mode in Sector 18


I understand that attached code is very lengthy and may be
dis-organised. i apologise for that. But i need this code working. i'm
unable to figure out.
Please help me out of it.


*****************BOOT LOader ********************
; USING NASM ASSEMBLER 0.98
section .text
global _start
ORG 0x7c00
_start:
load:
MOV AX,0x07e0
MOV ES,AX
MOV AH,2
MOV AL,17 ; Load 17 sectors into 0x00007e00 ; loads the setup code
MOV CL,2
MOV CH,00
MOV DX,0000
MOV BX,0000
mov dx,0000
INT 0x13

xor eax,eax
; Sector Number start from 1 for floppy; loads the protected code
MOV AX,0x0100
MOV ES,AX
MOV AH,2
MOV AL,1
MOV CX,18
MOV DX,0000
MOV BX,0000
mov dx,0000
INT 0x13
JC Print_mesg

JMP 0x07e0:0x0000 ; Test to see if it jumps or not

; JMP 0x00001000 ; Test to see if it jumps or not
; jmp 0x00007c00

........
.........

TIMES 510-($-$$) DB 0
dw 0xAA55
/***********************End of Boot Loader**************/

/********************Setup CODE ******************/
SECTION .text
global _start


; Let's kick out Real-Mode and enter Protected Mode..
[BITS 32]
_start:
CLI
xor eax,eax
mov ds,ax
mov es,ax
mov gs,ax
mov fs,ax
mov ss,ax
mov esp,0x00009000
lgdt [gdt_desc]

call init_idt

lidt [idt_start]

mov eax,0xb800
mov gs,eax
mov edi,0
MOV BYTE [gs:edi+6],'2' ; Just to make sure control comes here

;Code to switch to Protected Mode
mov eax,cr0
or eax,1
mov cr0,eax
; mov eax,0xb800
; mov gs,eax
; mov edi,0
; MOV BYTE [0xB800],'H'
; jmp $ ; If i enable this, it doesn't reboot

jmp 0x10:0x00001000 ; Rebooting Here at this point.

;/**********************/

[BITS 32]
init_idt:
MOV edx,ignore_int
mov eax,0x10
SHL eax,16
mov eax,edx
mov edx,0x8e00
MOV edi,idt_desc
mov ecx,0
mov ecx,256
rp_idt:
mov [edi],eax
mov [edi+4],edx
add edi,8
dec ecx
cmp ecx,0x0
jnz rp_idt
mov eax,0xb800
mov gs,eax
mov edi,0
MOV BYTE [gs:edi+2],'M'
ret
;/****************/

[BITS 32]
idt_start:
dw 256
dd idt_desc
idt_end:

idt_desc:
times 256*8-1 dd 0

;/****************/

ignore_int:
cld
push eax
push ecx
push edx
push es
push ds
mov ax,0x18
mov ds,ax
; mov es,eax
mov eax,20
mov ecx,1
push DWORD mesg_int
push Eax
push Ecx
call Print_Screen
add esp,12
pop eax
pop ds
pop es
pop edx
pop ecx
pop eax
; jmp $
iret
;/****************/

;/******************/
; Display Routine for 32-bit code
[BITS 32]
Print_Screen:
PUSH EBP
MOV EBP,ESP
MOV EDX,[Ebp+8]
MOV ECX,[EBP+0xc]
MOV SI,[EBP+0x10]
MOV EDI,0xB8000
MOV EAX,0x18
MOV DS,EAX
AGAIN1: MOV AH,byte [SI]
; MOV BYTE [DS:Edi],byte AH
MOV BYTE [DS:Edi],'A'
CMP EDX,1
JNZ NO_COLOR
ADD EDI,EDX
MOV BYTE [DS:EDI],3
SUB EDI,EDX
NO_COLOR:
INC SI
ADD di,2
DEC ECX
CMP ECX,0
JNZ AGAIN1
nop
POP EBP
RET
nop
nop
nop
;;/******************/

;SECTION .data
gdt_start:

NULL_gdt:

dd 0
dd 0

unused:
dd 0
dd 0

Code_gdt:

dw 0xFFFF
dw 0
db 0
db 10011010b
db 11001111b
db 0

data_gdt:
dw 0xFFFF
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:

gdt_desc:
dw gdt_end - gdt_start - 1
dd gdt_start

/*****************End of Setup Code *********************/

/***************Protected MOde ************************/

ECTION .text
extern _cl
global _start
; Let's kick out Real-Mode and enter Protected Mode..

[BITS 32]
;Code to execute after PMODE Switch happens
_start:
; jmp $
mov ax,0x18
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x90000

; test to see whether we r in protected or real mode
mov eax,0xb800
mov gs,eax
mov edi,0
MOV BYTE [gs:edi+4],'T' ; Should print this if we r in real
mode
jmp $
MOV BYTE [0xB8000],'P' ; Should print this if we r in
Protected mode.
MOV BYTE [0xB8002],'I'
MOV BYTE [0xB8004],'N'
MOV BYTE [0xB8006],'G'
MOV BYTE [0xB8008],'U'
jmp $
/************** End of Protected Mode ******************/


Expecting Positive Reply,

Regards,
-ANish


Frank Kotler <fbko...@comcast.net> wrote in message news:<40D164DF...@comcast.net>...

Ivan Korotkov

unread,
Jun 23, 2004, 4:04:31 PM6/23/04
to
On Wed, 23 Jun 2004 07:09:40 +0000 (UTC), Anish <ani...@lycos.com> wrote:

> Hi Frank,
>
> Thanx for your suggestion. i visited that website, but i couldn't find
> much information.
>
> Let me explain the problem completely i'm currently facing. I am
> unable to switch to protected mode. Jmp after PE bit set in CR0 is
> rebooting the machine.
> i would like to know the faulty code if any in the program.
> I really reached my patience limit as i have been debugging this from
> past 1 week.
>
> I am attaching my code. Can anybody figure out what's wrong with this
> code.
> 3 codes have been attached.
>
> BOOT LOader loads Setup and Protected Code at 0x00007e00 and
> 0x00001000 respectively.
>
> Bootloader ===> jumps to ====> 0x07e00:0000 ( setup Code )
> Setup COde ===> Jumps to ====> 0x10:0x00001000 ( Protected Mode Code )
>
> Setup code does GDT Initialization and switches to protected mode.
> One more thing i'm using script file to link. here is the procedure.

I haven't paid really much attention to the code, so I might be wrong, but
two things seem incorrect to me:

1) Setup code section begins with [BITS 32] But it's beginning runs in
real-mode, doesn't it? You probably should begin it with [BITS 16] and
place [BITS 32] after jmp, shouldn't you?

2) You load GDTR with contents of gdt_desc, but I don't see where you
update gdt_start. It is initialized with logical address of GDT (if I
understand NASM logic properly) but then you should shift CS by 4 and add
to gdt_start.

--
Ivan

Frank Kotler

unread,
Jun 23, 2004, 9:16:39 PM6/23/04
to
Anish wrote:
>
> Hi Frank,
>
> Thanx for your suggestion. i visited that website, but i couldn't find
> much information.

Hi Anish,

That URL was just for ndisasm documentation. For pmode advice, I'd start
with:

http://my.execpc.com/~geezer/

> Let me explain the problem completely i'm currently facing. I am
> unable to switch to protected mode. Jmp after PE bit set in CR0 is
> rebooting the machine.
> i would like to know the faulty code if any in the program.
> I really reached my patience limit as i have been debugging this from
> past 1 week.
>
> I am attaching my code. Can anybody figure out what's wrong with this
> code.
> 3 codes have been attached.
>
> BOOT LOader loads Setup and Protected Code at 0x00007e00 and
> 0x00001000 respectively.
>
> Bootloader ===> jumps to ====> 0x07e00:0000 ( setup Code )

I know it's only a comment, but you want 0x7e0:0000, no? (the code is
right)

I'm not familiar with the workings of linker scripts. I'd be tempted to
do the "setupcode" as "-f bin".

> Inside the FLOPPY:
> BootLoader in Sector 0
> Setup COde in Sector 1 to 17
> Protected Mode in Sector 18
>
> I understand that attached code is very lengthy and may be
> dis-organised. i apologise for that. But i need this code working. i'm
> unable to figure out.
> Please help me out of it.
>
> *****************BOOT LOader ********************
> ; USING NASM ASSEMBLER 0.98
> section .text
> global _start

Are you using "-f elf" and a linker script for this, too? I don't think
"-f bin" will swallow "global"...

> ORG 0x7c00
> _start:
> load:

You haven't set up ds. Since you're not accessing data in this part, I
guess it's okay...

> MOV AX,0x07e0
> MOV ES,AX
> MOV AH,2
> MOV AL,17 ; Load 17 sectors into 0x00007e00 ; loads the setup code
> MOV CL,2
> MOV CH,00
> MOV DX,0000
> MOV BX,0000
> mov dx,0000
> INT 0x13
>
> xor eax,eax

???

> ; Sector Number start from 1 for floppy; loads the protected code
> MOV AX,0x0100
> MOV ES,AX
> MOV AH,2
> MOV AL,1
> MOV CX,18
> MOV DX,0000
> MOV BX,0000
> mov dx,0000
> INT 0x13
> JC Print_mesg

If "Print_mesg" accesses data, you *will* need ds set.

> JMP 0x07e0:0x0000 ; Test to see if it jumps or not
>
> ; JMP 0x00001000 ; Test to see if it jumps or not
> ; jmp 0x00007c00
>
> ........
> .........
>
> TIMES 510-($-$$) DB 0
> dw 0xAA55
> /***********************End of Boot Loader**************/
>
> /********************Setup CODE ******************/
> SECTION .text
> global _start
>
> ; Let's kick out Real-Mode and enter Protected Mode..
> [BITS 32]

I'm pretty sure Ivan is right - this wants to start off in "bits 16" and
switch to "bits 32" as of the jump target. I'd do this in "-f bin" also,
and probably "org 7E00h"...

> _start:
> CLI
> xor eax,eax
> mov ds,ax
> mov es,ax
> mov gs,ax
> mov fs,ax
> mov ss,ax
> mov esp,0x00009000
> lgdt [gdt_desc]
>
> call init_idt
>
> lidt [idt_start]
>
> mov eax,0xb800
> mov gs,eax
> mov edi,0
> MOV BYTE [gs:edi+6],'2' ; Just to make sure control comes here
>
> ;Code to switch to Protected Mode
> mov eax,cr0
> or eax,1
> mov cr0,eax
> ; mov eax,0xb800
> ; mov gs,eax
> ; mov edi,0
> ; MOV BYTE [0xB800],'H'

I'd have guessed you'd reboot here (if uncommented). Once you've got cr0
bumped into pmode, this won't be a valid selector.

> ; jmp $ ; If i enable this, it doesn't reboot
>
> jmp 0x10:0x00001000 ; Rebooting Here at this point.
>
>
> ;/**********************/
>
> [BITS 32]

??? You're still in rmode when you call this, right?

> init_idt:
> MOV edx,ignore_int
> mov eax,0x10
> SHL eax,16
> mov eax,edx

??? You're setting up eax, and then overwriting it. Do you want "add"
here? (and do you really want to shl by 16?)

> mov edx,0x8e00
> MOV edi,idt_desc
> mov ecx,0
> mov ecx,256
> rp_idt:
> mov [edi],eax
> mov [edi+4],edx
> add edi,8
> dec ecx
> cmp ecx,0x0

The "cmp" is useless - the zero-flag is set/cleared by the "dec". Not a
problem, just "wasteful".

> jnz rp_idt
> mov eax,0xb800
> mov gs,eax
> mov edi,0
> MOV BYTE [gs:edi+2],'M'
> ret
> ;/****************/
>
> [BITS 32]
> idt_start:
> dw 256
> dd idt_desc
> idt_end:
>
> idt_desc:
> times 256*8-1 dd 0
>
> ;/****************/
>
> ignore_int:
> cld
> push eax
> push ecx
> push edx
> push es
> push ds
> mov ax,0x18

??? valid selector?

> mov ds,ax
> ; mov es,eax
> mov eax,20
> mov ecx,1
> push DWORD mesg_int
> push Eax
> push Ecx
> call Print_Screen
> add esp,12
> pop eax

??? Is this pushed?

> pop ds
> pop es
> pop edx
> pop ecx
> pop eax
> ; jmp $
> iret
> ;/****************/
>
> ;/******************/
> ; Display Routine for 32-bit code
> [BITS 32]
> Print_Screen:
> PUSH EBP
> MOV EBP,ESP
> MOV EDX,[Ebp+8]
> MOV ECX,[EBP+0xc]
> MOV SI,[EBP+0x10]
> MOV EDI,0xB8000
> MOV EAX,0x18

??? valid selector?

> MOV DS,EAX
> AGAIN1: MOV AH,byte [SI]
> ; MOV BYTE [DS:Edi],byte AH
> MOV BYTE [DS:Edi],'A'
> CMP EDX,1
> JNZ NO_COLOR
> ADD EDI,EDX
> MOV BYTE [DS:EDI],3
> SUB EDI,EDX
> NO_COLOR:
> INC SI
> ADD di,2
> DEC ECX
> CMP ECX,0
> JNZ AGAIN1
> nop
> POP EBP
> RET
> nop
> nop
> nop
> ;;/******************/
>
> ;SECTION .data

You may want to switch back to "bits 16" here.

Is this a valid selector?

> mov ds,ax
> mov es,ax
> mov fs,ax
> mov gs,ax
> mov ss,ax
> mov esp,0x90000
>
> ; test to see whether we r in protected or real mode
> mov eax,0xb800
> mov gs,eax
> mov edi,0
> MOV BYTE [gs:edi+4],'T' ; Should print this if we r in real
> mode

.... and will crash, probably reboot, if not! 0xB800 is almost certainly
*not* a valid selector.

> jmp $
> MOV BYTE [0xB8000],'P' ; Should print this if we r in
> Protected mode.
> MOV BYTE [0xB8002],'I'
> MOV BYTE [0xB8004],'N'
> MOV BYTE [0xB8006],'G'
> MOV BYTE [0xB8008],'U'
> jmp $
> /************** End of Protected Mode ******************/
>
> Expecting Positive Reply,

Is "good luck" positive enough???

Happy (re)bootin',
Frank

0 new messages