New to assembler

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
engine252

New to assembler

Post by engine252 »

i just started learning assembler and i get strange results

i would eventualy try to write a bootloader but before that i need some basic skill's so this is my first progie

i tryed to use bios interupt becauls i'll only need them

this is my code

Code: Select all

;   File: First.asm
;   First assembly program this program prints a message
;
;   To create executable using djgpp:
;   nasm -f coff first.asm
;   gcc -o first first.o

segment .data
   MSG DB "Dit is een test",13,10,"Cool he",0
;
;   initialized data is put in the data segment
;

segment .bss
;
;   uninitialized data is put in the bss segment
;

segment .text
   global _asm_main
      _asm_main:
         enter 0,0            ;setup routine
         pusha
         MOV AX,0x1301 
         MOV BX,0x0007 
         MOV CX,0x23 
         MOV BP,MSG 
         ADD BP,0x7C00 
         INT 0x10 

;
;   code is put in the text segment. Do not modify the code before
;   or after this comment
;
   popa
   mov eax,0               ;return back to C
   leave
   ret
this is my output when i run the program
i compiled the this like

nasm -f bin filename.asm -o filename.com

]_^Y├VWU??P???~
6?>JN t<1█????├?V■?
what am i doing wrong ???
bkilgore

Re:New to assembler

Post by bkilgore »

well, since this isn't actually a bootloader yet, you're pointing to the wrong memory location when you add 0x7c00 to msg to get the pointer to the string. You might want to try just getting rid of the add statement and trying that, but i'm not positive. That's assuming the compiler defaults to ORG at the right place that the COM file is loaded at, which i'm not positive about. But I think it'll work.
Ozguxxx

Re:New to assembler

Post by Ozguxxx »

Hey I am really sure but why arent you setting up segment registers? (just asking, Im not sure if its needed) I think int 10h with AH=10 needs es:bp as string buffer, so it might be a good idea to set up segment registers, or are they set up on system boot? Also I think you should set dx register, anyway if you are aware of these just ignore me :) ... Good luck. Also I want to ask sth, did you try to run the program on dos (on which program wont run) or did you test it on bochs or on hardware?
Schol-R-LEA

Re:New to assembler

Post by Schol-R-LEA »

The way this is set up is going to cause problems for a DOS COM program. First off, COM programs have to have an ORiGin of 0x0100, at least if you are assembling to binary. Second, because COM files are essentially raw binaries, and execution in them always begins immediately at offset 0x0100, you have to place any data or stack space after the main program code, not before it. Third, you can't declare separate segments for data, bss, stack and code, as COM files, by nature, have all of those in a single segment (unless you start mucking around with the segment registers directly). If you use [tt]SECTION[/tt] instead of [tt]SEGMENT[/tt], it should work out. Also, since NASM does not have any equivalent of ASSUME, you may need to set the DS and SS to match CS. For more information see section in the NASM manual on creating DOS COM programs. BTW, for a standalone program, you only need a .bss section if you have unintialized data.

As far as adding the origin address to the address of a label directly, that is almost never necessary; the assembler does those calculations for you in almost every case.

It looks to me as if you borrowed code from two different sources - one for DOS COM programs, the other perhaps for DJGPP DPMI programs - and tried to combine them. The [tt]ENTER[/tt] and [tt]LEAVE[/tt] instructions aren't necessary in this at all, for example; as a standalone program, you don't need to save or restore any previous state. COM programs don't usualy return using the [tt]RET[/tt] instruction (since, if the stack is misaligned, the system could hang), but with the DOS escape interrupt, INT 0x21, ah=0x4C.

Finally, the program as written will only print the very first character of the string; the BIOS functions only work on a single character at a time, not the while string. In order to print the whole string, you either need to use a loop, or else the DOS INT 0x21, ah=0x09 service call.
Post Reply