NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: IdleProgrammer on October 19, 2022, 10:03:03 PM
-
Greetings here in post
I have been trying to make a print function work between files and soon realized how particular the code can be.
Here my objectives were
1. make a (a)buffer or (b)buffering loop for the string
2. keep the version control steady to integrate between files & watch the program behavior
3. fix the print call between multiple files
Originally I got the first 2 steps to work using the dereference parenthesis however I can not check this in gdb due to a random SIGSEVI block for 90% cases.
If I try to combine methods other than mov ,[] such as{LEA,LDS,(bp,sp) stack buffer} I need to have this design code for addressing
Now I did in fact find one instance where I glimpsed into [] however I try restructuring my code to put all in the global print label and now
the code works only if I don't return from the settings function and run through the settings block instead.
The most frustrating part is that these sections are DUPLICATES of each other (post settings Call == print_string2 label)so I really have no clue anymore.
The programs files were made standard using a .bin for screening and .elf to debug in gdb where I am also adding the compiler commands.
I would really be avid if anyone else could show an answer about this and thank y'all for your time on this.
nasm -f bin print2.asm -o print2.bin
nasm -f elf print2.asm -o print2.o
ld -m elf_i386 -o print2 print2.o -e print
section .data
debugTest: db "debug test script",0
msgSeg3: db ?
length2: equ $-msgSeg3
placer equ 0x7c00
section .text
global print
print:
call settings
mov cx,[bx+si]
mov [placer+msgSeg+esi],cl
inc si
cmp cx,0x00
jnz print
mov esi,0
call continue
jmp loop
settings:
mov ebx,ecx
mov ax,0A000h
lea bx,msgTest1
add bx,placer
add dx,placer
mov ebp,esp
mov ah,0x0E
mov esi,0
print_string2:
mov cx,[bx+si]
mov [placer+msgSeg+esi],cl
inc si
cmp cx,0x00
jnz print_string2
push esi
mov esi,0
jmp continue
print_string:
mov ecx,[bx]
mov [placer+msgSeg+esi],cl
inc ebx
inc si
cmp cl,0x00
jnz print_string
push esi
mov esi,0
jmp continue
continue2:
mov al,[bp+si]
inc esi
int 0x10
cmp al,0x00
jnz continue2
continue3:
mov al,[es:esi]
inc esi
int 0x10
inc bp
mov cx,[placer+msgSeg+esi]
cmp al,0x00
jnz continue3
continue:
mov al,[placer+msgSeg+esi]
inc esi
int 0x10
inc bp
mov cx,[placer+msgSeg+esi]
cmp al,0x00
jnz continue
ret
.done:
pop esi
pop esi
ret
ret
loop:
jmp $
msgTest1: db "Testing the print",0
testLength: equ $-msgTest1
msgTest2: db "Text",0
testLength2: equ $-msgTest2
msgSeg: db ?
length: equ $-msgSeg
msgSeg2: db length
times 510 - ($-$$) db 0
dw 0xaa55
-
I'm not sure I understand what you are trying to do. The last two lines of code imply that you are trying to create a boot sector, but your first line of code is a call function, you use multiple segments, and you don't set up the segment registers, so I'd be surprised if you can get it to work anywhere.
-
Hello IdleProgrammer,
Welcome to the forum.
Perhaps I should stop right there...
Like Debs, I am unsure what you are trying to do.
Int 10h is 16 bit code.
-f elf is 32 bit code.
Huh? I see no possible chance this is going to work!
Can you explain more fully - or more clearly - what you are trying to do?
Best,
Frank
-
As I understood what you are trying to do, the binary format don't support external symbols (the code isn't 'linked' with other modules or libraries) and modern linkers don't support OBJ format (OMF). If you intend to link two or mode modules in a single "executable" you'll need to deal with old linkers like Borland's TLINK.
The easiest way to code multiple modules with binary format is to include the sources, like this:
; boot.asm
; To make sure we are dealiing the 16 bits code.
bits 16
; Binary format allows .text, .rodata and .data segments, in that order.
; But I prefer not to segmentize MBR codes.
;section .text
org 0x7c00 ; MBR will be loaded at 0:0x7c00 as per INT 0x19 BIOS specification.
; Don't need to export or define this symbol. Here's the MBR entrypoint.
;start:
; DS is initialized to CS by the BIOS, but doesn't hurt
; to initialize it ourselves.
push cs
pop ds
; Just to be sure (not necessary)
cld
lea si,[msg]
call printstr
.halt:
hlt
jmp .halt
; Here it is!
%include "printstr.inc"
; Our data area
msg:
db `Hello\r\n`,0
times 510 - ($ - $$) db 0
dw 0xaa55
; printstr.inc
; Entry: DS:SI - points to string buffer.
; Destroyed: AX,BX,SI
printstr:
lodsb
test al,al
jz .exit
mov ah,0x0e
mov bx,7 ; page 0, attribute: gray over black.
int 0x10
jmp printstr
.exit:
ret
$ nasm -fbin boot.asm -o boot.bin
$ qemu-system-i386 -drive file=boot.bin,index=0,media=disk.format=raw
But, if you really need multiple modules and use `ld` as your linker, you CAN comple your code to ELF32 format, but will need a linker script. Here's the two modules, a linker script and a Makefile:
# Makefile
boot.bin: boot.o printstr.o
ld -T boot.ld -o boot.bin boot.o printstr.o
boot.o: boot.asm
nasm -felf32 -o $@ $<
printstr.o: printstr.asm
nasm -felf32 -o $@ $<
/* boot.ld */
/* linker script for 16 bits - mbr */
OUTPUT_FORMAT(binary)
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0x7c00;
_begin = .;
_start = .;
.text : { *(.text16) *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
/* Puts MBR signature at offset 0x7dfe. */
. = _begin + 510;
.dummy : { BYTE(0x55); BYTE(0xAA); }
/* In this example I'll allocate .bss at the end of MBR. */
_bss_begin = .;
.bss : { *(.bss) }
_bss_end = .;
/* Here where the 'heap' start, if you need it. */
_heap = .;
/* Just as precaution: Discards these sections. */
/DISCARD/ : { *(.comment) *(.eh_frame) *(.note.GNU-stack) }
}
; boot.asm
bits 16
section .text
extern printstr
global _start
_start:
push cs
pop ds
cld
lea si,[msg]
call printstr
.halt:
hlt
jmp .halt
section .rodata
msg:
db `Hello\r\n`,0
; printstr.asm
bits 16
global printstr
; Entry DS:SI = ptr
printstr:
lodsb
test al,al
jz .exit
mov ah,0x0e
mov bx,7
int 0x10
jmp printstr
.exit:
ret
$ make
nasm -felf32 -o boot.o boot.asm
nasm -felf32 -o printstr.o printstr.asm
ld -T boot.ld -o boot.bin boot.o printstr.o
$ qemu-system-i386 -drive file=boot.bin,index=0,media=disk.format=raw
-
Thank you for the response. The code works perfectly and I really admire how optimized your program is. Now all I gotta do is learn how to load elf symbol tables to debug and I should be good to go. :)
-
Thank you for the response. The code works perfectly and I really admire how optimized your program is. Now all I gotta do is learn how to load elf symbol tables to debug and I should be good to go. :)
Thanks, but this is not "optimized". It is pretty basic code.
As for the symbol tables, you can't have them in a MBR code, since this isn't an "executable" file. It contains code that will be called by BIOS, but has no structure at all (just a bunch of bytes).