NASM Forum > Programming with NASM
creating a flat binary bigger than 64kB
Folkert van Heusden:
Hello,
For fun I'm developing an IBM PC emulator (before XT even). At the point it currently is I'm working on test-code to verify that the processor emulation is correct.
Unfortunately I'm stuck on far/inter-segment jumps.
According to http://computer-programming-forum.com/46-asm/bf904883c2cb61c7.htm it is/was possible to create binaries > 64kB yet in practice this fails.
e.g.:
org 0x800
xor ax,ax
mov si,ax
mov ss,ax
mov ax,0x800
mov sp,ax
; JMP NEAR
test_001:
mov si,0x1
jmp test_001a_ok
hlt
test_001a_ok:
; JMP FAR
test_003:
mov si,0x3
jmp far test_003_ok
hlt
hlt
hlt
resb 70000
hlt
hlt
hlt
test_003_ok:
nop
mov ax,0xa5ee
mov si,ax
hlt
This results in:
$ nasm -f bin jmp_call_ret_0.asm
jmp_call_ret_0.asm:20: error: binary output format does not support segment base references
jmp_call_ret_0.asm:24: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
I'm using nasm 2.16.01 as found in ubuntu
Any hints?
regards
p.s. yes this has been discussed on stackoverflow as well only the solutions there were work-arounds and I'm hoping to find a solution here to make it work without any trickery
Frank Kotler:
See if this helps:
https://www.nasm.us/xdoc/2.16.02rc1/html/nasmdoc8.html#section-8.1.
Best,
Frank
Folkert van Heusden:
--- Quote from: Frank Kotler on July 03, 2023, 08:39:34 AM ---See if this helps:
https://www.nasm.us/xdoc/2.16.02rc1/html/nasmdoc8.html#section-8.1.
Best,
Frank
--- End quote ---
Unfortunately not.
fredericopissarra:
In 16 bits mode (real mode) you cannot have more then 64 KiB in a single segment. Since you are not creating an EXE file, you cannot:
1 - Jump to another "segment" (there's only one);
2 - Declare uninitialized data (resb);
3 - Do a direct far jump or call...
This will compile, but will create the wrong code:
--- Code: --- org 0x800
xor ax,ax
mov si,ax
mov ss,ax
mov ax,0x800
mov sp,ax
mov [jmp_addr+2],cs
; JMP NEAR
test_001:
mov si,0x1
jmp test_001a_ok
hlt
jmp_addr:
dw test_003_ok
dw 0
test_001a_ok:
; JMP FAR
test_003:
mov si,0x3
jmp far [jmp_addr]
hlt
hlt
hlt
times 70000 nop
hlt
hlt
hlt
test_003_ok:
nop
mov ax,0xa5ee
mov si,ax
hlt
--- End code ---
Because that times 70000 nop will get you an image bigger than 64 KiB, so test_003_ok will be a reference inside your code segment (not outside)... test_003_ok will be offset 0x1_1196. but the offset reference in jmp_addr will be 0x1196, thus, wrong!
You can use 386 instructions in real mode and "normalize" the "physical address" like this:
--- Code: --- ...
mov eax,test_003_ok ; this will be a 32 bits offset.
mov bx,cs
movzx ebx,bx
shl ebx,4
add eax,ebx ; EAX has the "physical address" of test_003_ok.
mov ebx,eax
and ax,0x0f
shr ebx,4 ; BX:AX is now the logical "normzlized" address of test_003_ok
mov [jmp_addr],ax
mov [jmp_addr+2],bx
jmp far [jmp_addr]
jmp_addr:
dw 0, 0
...
--- End code ---
Notice you'll have to calculate seg:offset to access anything beyond the first segment. (and I don't know if this will work with a .COM file no MS-DOS, for example).
Deskman243:
This question is pretty intriguing to me as I had to make a good amount of posts here to try and answer this. Currently what I understand is that x86-16 is based on 8086 processors. Now the design itself is built on a certain amount of data lines as previously mentioned
--- Quote ---In 16 bits mode (real mode) you cannot have more then 64 KiB in a single segment.
--- End quote ---
This is because the logical address is built from the A20 data lines. This clarifies the A1-16 controls for the standard segmentation for these programs. Now the meaning of the rest of the lines infers the area passed 64kb (0xFFFF + 1 =64kb and 0xFFFFF + 1 = 1 MB). What I'm trying to get is whether these segments > 0x0FFFF are reserved in a way or more of a reserve for say one type of thing.
--- Quote ---Notice you'll have to calculate seg:offset to access anything beyond the first segment.
--- End quote ---
My previous post was on how data is accessed by these segments because I could only ever get data reference passed 64kb. Other than that I was researching disk reading to perhaps get an answer on the correlated links below.
Adjusting segments for linux linker commands and build files
https://forum.nasm.us/index.php?topic=3881.0
Disk Routines under NASM
https://forum.nasm.us/index.php?topic=3884.0
Navigation
[0] Message Index
[#] Next page
Go to full version