From: Frank K. <fbk...@co...> - 2006-11-08 22:08:43
|
Ejaz Ahmed wrote: > hello to all nasm users Hi Ejaz, (cool name!) > i am taking a first course on microprocessors. in lab we are using masm.i am > using kubuntu 6.06 at home. so i decided to use nasm. Two steps in the right direction! > since we have only > studied three statements commands of 8086/8088 microprocessor and our > instructor kept us in abstraction and promised us to tell bout starting > statements after a week. so i am sending a masm code and request you to > convert it into a valid nasm code and also commands of gdb (or some other > debugger) to check the values in each register. > here is masm code > > code_seg segment 'code' > assume cs:code_seg > main proc far > > mov ax,50h > mov bx,60h > mov cx,ax > add ax,ax ;2*ax > mov dx,ax ;dx=2ax > add ax,ax ;ax=4ax > add ax,dx ;ax=6ax > add ax,cx ;ax=7ax > mov dx,ax ;dx=7ax > mov cx,bx > add bx,bx > add cx,bx > sub dx,cx > > main endp > code_seg ends > end The good news is that the actual "code" won't have to be changed at all. Some of the "cruft" at the beginning and end require some changes. Like so... ; nasm -f elf -g myprog.asm ; ld -o myprog myprog.o global _start section .text _start: nop mov ax,50h mov bx,60h mov cx,ax add ax,ax ;2*ax mov dx,ax ;dx=2ax add ax,ax ;ax=4ax add ax,dx ;ax=6ax add ax,cx ;ax=7ax mov dx,ax ;dx=7ax mov cx,bx add bx,bx add cx,bx sub dx,cx xor ebx, ebx ; I didn't see an error! :) mov eax, 1 ; __NR_exit int 80h Notice I've added an explicit "exit" (first thing we have to learn is how to exit!) The "nop" at the beginning is a "parking place for gdb". Gdb is happier if there's a one-byte opcode to stop on. The bad news is that I can't get gdb to step through it right now. I think I've done it before... I'm not smart enough to run gdb. I use ald, Patrick Alken's "Assembly Language Debugger" (SourceForge), and an older version (0.1.7) at that, because it's "more like debug". Faint praise, that I like a debugger 'cause it's "more like debug"... But the only command I need is "step"... I know that you can make gdb a little more "Nasm-friendly" by having a ".gdbinit" file in your home directory... Here's one that Jeff Owens posted, some time ago... # gdb initialization file, it must reside at ~/.gdbinit or ./.gdbinit # # define special help command "h" that shows asm related commands only # define h echo -------\n echo asm debugging commands, see "help" for other gdb comands\n echo \ \n echo g <adr> exec & set temp break <adr> u <n> disassemble from pc n times\n echo c run program (continue) uu <adr> <n> disassemble from adr n times\n echo n step one instruction ss <n> show stack n locations\n echo nn step but do not enter calls r show registers\n echo until step or run to end of loop db <adr> <n> display bytes\n echo \ dw <adr> <n> display words\n echo q quit gdb dd <adr> <n> display dword\n echo \ ds <adr> <n> display string\n echo bs show breaks \n echo bc clear breaks \n echo \n echo modifying the code within gdb requires reload, recompile easier? \n echo to change register -> set $eax = 0x123456 \n echo ------\n end # # set gdb initialization flags - change these as needed # # eliminate the pesky exit message that says program is running set confirm off set language asm set disassembly-flavor intel # enable the following to work in hex, the default is decimal set output-radix 16 set input-radix 16 # # disable pesky hook messages?? this may not be necessary in other versions of gdb # define hook-stop end define hook-continue end #------------- define special commands for assembler ------------------- # # go (run) to temporary break location "g <label>" # define g tbreak $arg0 continue x/1i $pc echo ----------\n end # # show stack "ss <n>" where n is number of entries to show # define ss x/$arg0xh $esp-(4 * $arg0) end # # define nn to single step over calls # define nn echo -------------- exti printf "eax=%x ebx=%x ecx=%x edx=%x esi=%x edi=%x ebp=%x esp=%x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp x /4i $pc end # # define n to single step one instruction # define n echo --------------- si printf "eax=%x ebx=%x ecx=%x edx=%x esi=%x edi=%x ebp=%x esp=%x eflags=%x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp,$eflags #disassemble $pc $pc+14 x /4i $pc end # # define "u <n>" to disassemble n locations from $pc # define u x/$arg0i $eip # disassemble $eip $eip+$arg0 end # # define "uu <label> <n>" to disasseble n locatons from given label # define uu x/$arg1i $arg0 # disassemble $arg0 $arg0+$arg1 end # # define "bs" show breaks # define bs info break end # # define "bc" clear all breakpoints # define bc delete end # # define "r" show registers # define r echo -----\n printf "eax=%x ebx=%x ecx=%x edx=%x esi=%x edi=%x ebp=%x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp printf "esp=%x eip=%x flag=%x --> O D I T S Z - AC - P - C\n",$esp,$eip,$eflags echo flags= Overflow, Direction, Interrupt, Trap, Sign, Zero, AuxCarry, Parity, Carry\n x/i $pc echo -----\n end # # define "db <adr> <n>" display <n> bytes at <adr> # define db x/$arg1xb $arg0 end # # define "dw <adr> <n>" display <n> words at <adr> # define dw x/$arg1xh $arg0 end # # define "dd <adr> <n>" display <n> dwords at <adr> # define dd x/$arg1xw $arg0 end # # define "ds <adr> <n>" display <n> char(ascii) at <adr> # define ds x/$arg1xc $arg0 end # # start of code initialization ---------------------- # # to initialize gdb we need to use the "run" command once, first # we display the current instruction, then set a break at next location. # Warning - the first instruction must be one byte long. # Next, we start t# gdb initialization file, it must reside at ~/.gdbinit or ./.gdbinit # # define special help command "h" that shows asm related commands only # define h echo -------\n echo asm debugging commands, see "help" for other gdb comands\n echo \ \n echo g <adr> exec & set temp break <adr> u <n> disassemble from pc n times\n echo c run program (continue) uu <adr> <n> disassemble from adr n times\n echo n step one instruction ss <n> show stack n locations\n echo nn step but do not enter calls r show registers\n echo until step or run to end of loop db <adr> <n> display bytes\n echo \ dw <adr> <n> display words\n echo q quit gdb dd <adr> <n> display dword\n echo \ ds <adr> <n> display string\n echo bs show breaks \n echo bc clear breaks \n echo \n echo modifying the code within gdb requires reload, recompile easier? \n echo to change register -> set $eax = 0x123456 \n echo ------\n end # # set gdb initialization flags - change these as needed # # eliminate the pesky exit message that says program is running set confirm off set language asm set disassembly-flavor intel # enable the following to work in hex, the default is decimal set output-radix 0x10 set input-radix 0x10 # # disable pesky hook messages?? this may not be necessary in other versions of gdb # define hook-stop end define hook-continue end #------------- define special commands for assembler ------------------- # # go (run) to temporary break location "g <label>" # define g tbreak $arg0 continue x/1i $pc echo ----------\n end # # show stack "ss <n>" where n is number of entries to show # define ss x/$arg0xh $esp-(4 * $arg0) end # # define nn to single step over calls # define nn echo -------------- exti printf "eax=%x ebx=%x ecx=%x edx=%x esi=%x edi=%x ebp=%x esp=%x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp x /4i $pc end # # define n to single step one instruction # define n echo line- si printf "eax=%x ebx=%x ecx=%x edx=%x esi=%x edi=%x ebp=%x esp=%x eflags=%x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp,$esp,$eflags #disassemble $pc $pc+14 x /4i $pc end # # define "u <n>" to disassemble n locations from $pc # define u # x/$arg0i $eip # disassemble $eip $eip+$arg0 disassemble $arg0 end # # define "uu <label> <n>" to disassemble n locations from given label # define uu x/$arg1i $arg0 # disassemble $arg0 $arg0+$arg1 end # # define "bs" show breaks # define bs info break end # # define "bc" clear all breakpoints # define bc delete end # # define "r" show registers # define r echo -----\n printf "eax=%x ebx=%x ecx=%x edx=%x esi=%x edi=%x ebp=%x\n",$eax,$ebx,$ecx,$edx,$esi,$edi,$ebp printf "esp=%x eip=%x flag=%x --> O D I T S Z - AC - P - C\n",$esp,$eip,$eflags echo flags= Overflow, Direction, Interrupt, Trap, Sign, Zero, AuxCarry, Parity, Carry\n x/i $pc echo -----\n end # # define "db <adr> <n>" display <n> bytes at <adr> # define db x/$arg1xb $arg0 end # # define "dw <adr> <n>" display <n> words at <adr> # define dw x/$arg1xh $arg0 end # # define "dd <adr> <n>" display <n> dwords at <adr> # define dd x/$arg1xw $arg0 end # # define "ds <adr> <n>" display <n> char(ascii) at <adr> # define ds x/$arg1cb $arg0 end # attempt a string display... define dstr x /1sb &$arg0 end # # start of code initialization ---------------------- # # to initialize gdb we need to use the "run" command once, first # we display the current instruction, then set a break at next location. # Warning - the first instruction must be one byte long. # Next, we start the program executing (run) then clear all breakpoints. # # x /1i *_start # echo --------------- # break *_start+1 # run # delete # x /1i *_start+1 echo \n---------\n echo for some reason nasm symbols appear as functions? ignore\n echo symbol related warnings.\n echo \n echo -------- ty%s, %s%s Good luck with it. If all else fails, we can come up with a routine to *print* the damn value (even call printf, if we want to)... Best, Frank |