Prev: NASM HelloWorld - DOS
Next: ELF loading
From: Frank Kotler on 13 Aug 2007 13:14 Rod Pemberton wrote: .... > Yeah, but if he wanted the jump in BITS32 he should be able to put an > operand size override prefix, o16, right? Like so: > > [BITS 32] > o16 jmp 08h:clear_pipe ; Jump to code segment, offset > clear_pipe: > mov ax, 10h ; Save data segment identifyer > mov ds, ax I guess that would work (I've not run it). Why would he want to increase the confusion? Best, Frank
From: Frank Kotler on 13 Aug 2007 13:36 Rod Pemberton wrote: .... > Actually, just as an FYI, I'm using an 'o32 retf' in a 'BITS 16' section. > The retf instruction will allow you to use CS:EIP values you can't use in a > jmp and let's you use computed CS:EIP values. Okay. > Also, although I don't see > much NASM code without the brackets, technically you should be using BITS 32 > or BITS 16 without brackets. Why do you say that? There's a difference between "section .text" and "[section .text]" - the former is a macro which expands to the latter *and* sets "__SECT__". "bits 32" is a macro that expands to "[bits 32]", but has no side effects. What's the advantage? (I used to use "[section .text]" and "[org 100h]", etc. 'cause I thought it looked cool. I have decided that it looks cooler to reserve "[]" for "[contents_of_memory]"...) (some constructs - "[list +/-]" and "[map ...]" come to mind, don't have a "non-bracketted" form...) Best, Frank
From: Matt on 13 Aug 2007 13:45 opexoc(a)gmail.com wrote: > Hello, > > look at some piece of code which is to be booted by BIOS at startup > and enter CPU into protected mode: > > 1[BITS 16] ; We need 16-bit intructions for Real mode > 2 > 3 [ORG 0x7C00] ; The BIOS loads the boot sector into memory > location 0x7C00 4 > 5 cli ; Disable interrupts, we want to > be alone > 6 > 7 xor ax, ax > 8 mov ds, ax ; Set DS-register to 0 - used by > lgdt > 9 > 10 lgdt [gdt_desc] ; Load the GDT descriptor > 11 > 12 mov eax, cr0 ; Copy the contents of CR0 into > EAX > 13 or eax, 1 ; Set bit 0 > 14 mov cr0, eax > 15 ; Copy the contents of EAX into > CR0 > 16 ;[BITS 32] > 17 jmp 08h:clear_pipe ; Jump to code segment, offset > clear_pipe > 18 [BITS 32] > 19 clear_pipe: > 20 mov ax, 10h ; Save data segment identifyer > 21 mov ds, ax > > In which location directive [BITS 32] should appear ( first or > second )? When I use first location then computer hang on and doesn't > execute properly code in clear_pipe. When I change first bit in cr0 > register then I enter into protected mode so I should use 32 bit > instruction. Despite of this fact only when I use second directive > [BITS 32] ( without first ) everything works ok. > > Wiktor > The problem here is that you are telling the ASSEMBLER, not the CPU what to do. The CPU is really in PM from the time you change the flag, but you then need to do a jump to reload the CS register with a valid selector. You need to tell the assembler that your jump is a PM mode jump. I get around this by putting the following: use16 ....... ; Switch to protected mode ; and write a message mov eax,cr0 or al,1 mov cr0,eax db 0eah dw start_32,K_CODE_SEL,0,0,0,0 ; code restarts in 32 bit ; mode at start_32 ; these are the 16 bit text access routines. include '%workdir%\booting\text_access.asm' ; 32 bit code starts here use32 spacer db '32 bit code starts here',0 start_32: ; Set up the segment registers straight away. xor eax,eax mov es,ax mov fs,ax mov ax,K_VIDEO_SEL mov es,ax mov gs,ax mov ax,K_DAT_SEL mov fs,ax mov ax,K_ALIAS_SEL mov ds,ax ; Set the stack seg and pointer mov ebx,K_STACK_POINTER mov ax,K_DAT_SEL mov ss,ax mov esp,ebx ; Put welcome string mov esi,str_pmode ;stdcall putstring32 The first instructions are actually the hard-coded instruction for the jump. This stops the assembler trying to think on my behalf :-) Matt
From: Bx.C / x87asm on 13 Aug 2007 14:53 > Yeah, but if he wanted the jump in BITS32 he should be able to put an > operand size override prefix, o16, right? Like so: > > [BITS 32] > o16 jmp 08h:clear_pipe ; Jump to code segment, offset > clear_pipe: > mov ax, 10h ; Save data segment identifyer > mov ds, ax so instead of: EA,xx,xx,08,00 16-bit... jmp 0008:clear_pipe you have it create: 66,EA,xx,xx,08,00 ummmm,... no! well, go ahead and try it, but ... in a 16-bit CS (since CS descriptor is still in 16 bit mode until after the jump), that makes an incomplete instruction... so it will pull two more bytes from the next instruction... you end up with this instead: 66,EA,xx,xx,08,00,66,B8 which is jmp 0B866h:(0080*10000h+clear_pipe) no.. I don't think that'll work at all for you This is why the jump is placed at the end of the 16-bit section. -- Bx.C
From: Rod Pemberton on 14 Aug 2007 03:32
"Bx.C / x87asm" <email.address(a)is.invalid> wrote in message news:f9q9bh$ms$1(a)aioe.org... > > Yeah, but if he wanted the jump in BITS32 he should be able to put an > > operand size override prefix, o16, right? Like so: > > > > [BITS 32] > > o16 jmp 08h:clear_pipe ; Jump to code segment, offset > > clear_pipe: > > mov ax, 10h ; Save data segment identifyer > > mov ds, ax > > so instead of: > > EA,xx,xx,08,00 16-bit... jmp 0008:clear_pipe > > you have it create: > > 66,EA,xx,xx,08,00 > > ummmm,... no! No, it creates (due to BITS 32...): 66,EA,xx,xx,yy,yy,08,00 Which is told by 0x66 to execute as: EA,xx,xx,08,00 I.e, the dword offset reduced to word offset... Correct? (BTW, it does work...) Rod Pemberton |