Reputation: 87291
I'm looking for the equivalent of the following assembly program with TASM, i.e. creating a 32-bit binary file with nonzero org. Here is how it works with NASM:
; $ nasm -O0 -f bin -o id.bin id.nasm
bits 32
cpu 386
org 432100h
mov eax, foo
push eax
foo:
; $ ndisasm -b 32 id.bin
; 00000000 B806214300 mov eax,0x432106
; 00000005 50 push eax
Is it possible to do the same with a combination of TASM and TLINK? How would the .asm file look like? What are the compilation command lines?
Please note:
The output file must be 6 bytes long (see hex dump above), without any headers.
It's really TASM+TLINK. In this question I'm not looking for alternatives. (NASM can obviously do it, see above.)
The org
must be 432100h. It's not OK to use org 0
and mov eax, foo+432100h
.
Some context: I have a moderately complex x86 32-bit assembly program with binary file output, and I'm curious if it would be possible to port it to TASM.
Upvotes: 4
Views: 120
Reputation: 87291
I ended up writing my own linker, folink2 for this (see C89 impelementation, TASM 2.0 implementation for DOS 8086).
The linker just copies the raw data bytes (expanding RLE-compressed LIDATA records) from the .obj file to the raw binary output file, and it checks that there are no relocations (fixupps).
Here is an example 32-bit program (also available here), written in TASM assembly (works with TASM 1.0 or later):
ideal
program_base equ 8048000h ; Typical Linux i386 executable program.
p386n
segment _TEXT use32 ; The segment name is arbitrary.
assume cs:_TEXT, ds:_TEXT, es:_TEXT, ss:_TEXT
org program_base
file_header:
Elf32_Ehdr: OSABI_Linux equ 3
db 7Fh,'ELF',1,1,1,OSABI_Linux,0,0,0,0,0,0,0,0,2,0,3,0
dd 1,_start,Elf32_Phdr-file_header,0,0
dw Elf32_Phdr-file_header,20h,1,0,0,0
Elf32_Phdr: dd 1,0,program_base,0,prebss-program_base,mem_end-program_base,7,1000h
_start: mov eax, 4 ; SYS_read.
mov ebx, 1 ; STDOUT_FILENO.
mov ecx, offset msg
mov edx, msg_end-msg
int 80h ; Linux i386 syscall.
mov eax, 1 ; SYS_exit.
xor ebx, ebx ; EXIT_SUCCESS == 0.
int 80h ; Linux i386 syscall.
msg: db 'Hello, World!', 10
msg_end:
prebss: db ((file_header-$) and 3) dup (?)
bss:
; These variables are initialized to zero by the Linux kernel.
; No extra bytes are generated for them.
unused_array: db 42 dup (?)
unused_var: dw ?
mem_end:
ends
end
After generating the file.obj
with tasm file.asm
, the folink2 linker can be used to generate the raw binary file: folink2t.com file.obj file
.
The same linker can be used for 16-bit x86 raw binary output, see example TASM source.
Upvotes: 3
Reputation: 87291
I managed to make it work with TASM+WLINK (rather than TASM+TLINK), using TASM 4.1 and the WLINK from OpenWatcom v2.
Here is my id.asm file:
.386
.model flat
.stack 100h ; Dummy, to pacify TASM.
mov eax, offset foo
push eax
foo:
end foo ; Dummy reference to foo, to pacify TASM.
Here is how I compile it:
tasm /t id.asm
wlink format raw bin option offset=0x432100 option quiet name idw.bin file id.obj
ndisasm -b 32 idw.bin
Output:
00000000 B806214300 mov eax,0x432106
00000005 50 push eax
Here is an alternative id.asm file, using TASM ideal mode:
p386n
model flat
stack 100h ; Dummy, to pacify TASM.
codeseg
mov eax, offset foo
push eax
foo:
end foo ; Dummy, to pacify TASM.
Unfortunately most early versions of WLINK (such as in Watcom C/C++ 11.0B, the last release before OpenWatcom) don't support format raw
.
Upvotes: 2