Ok so i have this floppy image that just prints a message now the problem that i am running into is that i have to jump to memory location 0x1000 and then jump back to the original place but have no clue how to do it this is what mbr looks like on the floppy: (i am using nasm)

org 0x7c00
xor ax,ax
mov es,ax
mov ah,0
mov al,3
int 10h

mov ah,13h
mov al,1
mov bh,0
mov bl,0ah
mov cx,mlen
mov dh,0
mov dl,0
mov bp, msg
int 10h

[B];jump to 0x1000 here
;print '$' here[/B]

mov dh,1
msg db "This is a message"
mlen equ $-msg
times 512-($-$$)-2 db 0
dw 0AA55h

Dani AI

Generated

Short, practical plan for jumping to 0x1000 from a boot sector and coming back (answers ). The missing pieces in the thread are (1) there must actually be code at the linear address you want to run, (2) the stack must live somewhere it will not get overwritten, and (3) the transfer must change CS:IP the right way so the callee can return. was right to ask whether “0x1000” is a physical address or a segment — that matters for how you form the jump.

How to do it in three steps (high level):

  • Place the second-stage code at linear address 0x1000 before transferring control. BIOS does not put your code there for you, so either copy it from the boot sector into that memory or use a BIOS disk read to load extra sectors into that spot.
  • Put the stack in a safe area (a segment that does not overlap your code), initialize SS:SP accordingly, and remember the stack grows downward.
  • Transfer control using a far transfer if you change segment (so the callee can use a far return). If you stay in the same segment you can use a near jump/call.

Minimal read + far-transfer pattern (illustrative):

; set ES:BX to target buffer (linear 0x1000 = 0000:1000)
mov ax, 0x0000
mov es, ax
mov bx, 0x1000

; BIOS read (AH=2) — DL should contain boot drive
mov ah, 0x02
mov al, 1       ; sectors to read
mov ch, 0
mov cl, 2
mov dh, 0
int 0x13
jc load_failed

; far-transfer via stack trick: push seg then push off, retf will load IP then CS
push word 0x0000
push word 0x1000
retf

Troubleshooting notes: check DL (drive number), test the carry flag after INT 13h, avoid placing SS:SP so the stack overlaps 0x1000, and test in an emulator (QEMU/Bochs) or with a floppy image before writing hardware. This complements ’s stack/call idea and answers the physical-vs-segment question raised by .

Recommended Answers

All 6 Replies

I updated my boot disk that I made some time ago...It now supports a function call and a stack. The functionality I added is from any information I could find on Google so I can noway guarantee that this is the correct way to do this, all I know is that its works on my old PII computer....

assem code

.code16

.section .data

.section .text
	.global _start
_start:
			movw	$0xb800, %ax
			movw	%ax, %es
			movw	$0x8000, %ax
			movw	%ax, %ss
			movw	$0xfffe, %sp



			call	tohere
		
loop1:
			jmp	loop1


tohere:
			movb	$0x47, %es:0
			movb	$0x1f, %es:1

			movb	$0x34, %es:2
			movb	$0x1f, %es:3

			movb	$0x31, %es:4
			movb	$0x1f, %es:5

			movb	$0x34, %es:6
			movb	$0x1f, %es:7

			movb	$0x33, %es:8
			movb	$0x1f, %es:9

			movb	$0x20, %es:10
			movb	$0x1f, %es:11	

			movb	$0x48, %es:12
			movb	$0x1f, %es:13	

			movb	$0x61, %es:14
			movb	$0x1f, %es:15	

			movb	$0x63, %es:16
			movb	$0x1f, %es:17

			movb	$0x6b, %es:18
			movb	$0x1f, %es:19

			movb	$0x65, %es:20
			movb	$0x1f, %es:21	

			movb	$0x72, %es:22
			movb	$0x1f, %es:23			

			movb	$0x20, %es:24
			movb	$0x1f, %es:25	

			movb	$0x46, %es:26
			movb	$0x1f, %es:27	

			movb	$0x6f, %es:28
			movb	$0x1f, %es:29

			movb	$0x72, %es:30
			movb	$0x1f, %es:31

			movb	$0x75, %es:32
			movb	$0x1f, %es:33	

			movb	$0x6d, %es:34
			movb	$0x1f, %es:35	

			movb	$0x73, %es:36
			movb	$0x1f, %es:37					

			movb	$0x20, %es:38
			movb	$0x1f, %es:39

			ret

These are the lines that I set up my stack. I move 0x8000 hex into the ss segment register and initialize the stack pointer to 0xfffe. Like I said I'm not sure if this is correct all I know is it works on my old PII

movw	$0x8000, %ax
			movw	%ax, %ss
			movw	$0xfffe, %sp

The code's in At&t syntax, sorry all I know. From this exe I stripped out the pertinent sections(everything but the header and footer) and did a little AWK magic and ended up with the hex array below

C code

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>

char boot_buf[512] =	{ 
0xB8,0x00,0xB8,0x8E,0xC0,0xB8,0x00,0x80,0x8E,0xD0,0xBC,0xFE,0xFF,0xE8,0x02,0x00,0xEB,0xFE,0x26,
0xC6,0x06,0x00,0x00,0x47,0x26,0xC6,0x06,0x01,0x00,0x1F,0x26,0xC6,0x06,0x02,0x00,0x34,0x26,0xC6,
0x06,0x03,0x00,0x1F,0x26,0xC6,0x06,0x04,0x00,0x31,0x26,0xC6,0x06,0x05,0x00,0x1F,0x26,0xC6,0x06,
0x06,0x00,0x34,0x26,0xC6,0x06,0x07,0x00,0x1F,0x26,0xC6,0x06,0x08,0x00,0x33,0x26,0xC6,0x06,0x09,
0x00,0x1F,0x26,0xC6,0x06,0x0A,0x00,0x20,0x26,0xC6,0x06,0x0B,0x00,0x1F,0x26,0xC6,0x06,0x0C,0x00,
0x48,0x26,0xC6,0x06,0x0D,0x00,0x1F,0x26,0xC6,0x06,0x0E,0x00,0x61,0x26,0xC6,0x06,0x0F,0x00,0x1F,
0x26,0xC6,0x06,0x10,0x00,0x63,0x26,0xC6,0x06,0x11,0x00,0x1F,0x26,0xC6,0x06,0x12,0x00,0x6B,0x26,
0xC6,0x06,0x13,0x00,0x1F,0x26,0xC6,0x06,0x14,0x00,0x65,0x26,0xC6,0x06,0x15,0x00,0x1F,0x26,0xC6,
0x06,0x16,0x00,0x72,0x26,0xC6,0x06,0x17,0x00,0x1F,0x26,0xC6,0x06,0x18,0x00,0x20,0x26,0xC6,0x06,
0x19,0x00,0x1F,0x26,0xC6,0x06,0x1A,0x00,0x46,0x26,0xC6,0x06,0x1B,0x00,0x1F,0x26,0xC6,0x06,0x1C,
0x00,0x6F,0x26,0xC6,0x06,0x1D,0x00,0x1F,0x26,0xC6,0x06,0x1E,0x00,0x72,0x26,0xC6,0x06,0x1F,0x00,
0x1F,0x26,0xC6,0x06,0x20,0x00,0x75,0x26,0xC6,0x06,0x21,0x00,0x1F,0x26,0xC6,0x06,0x22,0x00,0x6D,
0x26,0xC6,0x06,0x23,0x00,0x1F,0x26,0xC6,0x06,0x24,0x00,0x73,0x26,0xC6,0x06,0x25,0x00,0x1F,0x26,
0xC6,0x06,0x26,0x00,0x20,0x26,0xC6,0x06,0x27,0x00,0x1F,0xC3
			};

int main(int argc, char**argv)
{
	int floppy_desc;

boot_buf[510]=0x55;//to make the floppy/image bootable
boot_buf[511]=0xaa;//to make the floppy/image bootable

floppy_desc=open("/dev/fd0",O_RDWR);
lseek(floppy_desc,0,SEEK_CUR);
write(floppy_desc,boot_buf,512);
close(floppy_desc);
}

This will create a boot disk for a Intel machine that will create a stack and then call a function that will display some text and then loop forever...Note this program will only compile on a Linux box because of this line:

floppy_desc=open("/dev/fd0",O_RDWR);

If you plan to use this on a windows box you'll have to port it...

With this example you should be able to call anywhere within your code section letting the call/ret opcodes and the stack sweat the details...

Your origin in 7C00h indicated that you were booted
by the BIOS, but you want to jump to 0x1000?
When you've loaded nothing there???
Is 0x1000 a physical or segment address?

If it is a segment adress to transfer control to code a 1000:0000
and be able to return you would use a
far CALL and the called routine would use RETF to return.

CALL word 0x1000:0x0

To set up stack 64KB in length for segment number
0x8000, you would load SP with 0000, it may sound strange
but when something is pushed on the stack 0000 will become
FFFE because PUSH decrements SP by -2, hence every byte
of the stack will be used.

mov ax, 0x8000
mov ss, ax
mov sp, 0x0

To set up stack 64KB in length for segment number
0x8000, you would load SP with 0000, it may sound strange
but when something is pushed on the stack 0000 will become
FFFE because PUSH decrements SP by -2, hence every byte
of the stack will be used.

mov ax, 0x8000
mov ss, ax
mov sp, 0x0

Yeah that is weird. I only guessed at that part because I couldn't find any doc's on initializing the stack pointer, but I knew the stack started high and worked its way down...Good bit of info. Thanks...

please help me to learning programing viruses by assembly language
please help me to learning programing viruses by assembly language
please help me to learning programing viruses by assembly language
please please please please please please please please please please please please

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.