- Write a C program to test Palindrome Numbers. Write a C program for matrix multiplication. Write a C program to find transpose a matrix. Write a C program to add two matrix. Write a C program for insertion sort. Write a program to find the factorial of 5 in 8086. Write an assembly language program to display the.
- 🏡 Stay Home Stay Safe🌟 Please leave a LIKE ️ and SUBSCRIBE for more AMAZING content! 🌟📸 Instagram: Website.
Input and display a string from an array in assembly using nasm « on: June 02, 2014, 01:56:59 AM » The following code runs, however, any character entered is displayed with the same symbol (an o shape underlined?). Assembly language program for various string operations Write an assembly language program (Intel 8086) to READ A STRING, CONVERT IT INTO UPPER CASE AND FINALLY DISPLAY THE CONVERTED STRING Computer Microprocessor and Archtiecture / January 16, 2012 / Leave a Comment.
Introduction
This document contains very brief examples of assembly languageprograms for the x86. The topic of x86 assembly language programming ismessy because:
- There are many different assemblers out there: MASM, NASM, gas,as86, TASM, a86, Terse, etc. All use radically different assemblylanguages.
- There are differences in the way you have to code for Linux,OS/X, Windows, etc.
- Many different object file formats exist: ELF, COFF, Win32,OMF, a.out for Linux, a.out for FreeBSD, rdf, IEEE-695, as86, etc.
- You generally will be calling functions residing in the operating system orother libraries so you will have to know some technical details abouthow libraries are linked, and not all linkers work the same way.
- Modern x86 processors run in either 32 or 64-bit mode; there arequite a few differences between these.
We’ll give examples written for NASM, MASM and gas for both Win32and Linux. We will even include a section on DOS assembly languageprograms for historical interest. These notes are notintended to be a substitute for the documentation that accompaniesthe processor and the assemblers, nor is it intended to teach youassembly language. Its only purpose is to show how to assembleand link programs using different assemblers and linkers.
Assemblers and Linkers
Regardless of the assembler, object file format, linker oroperating system you use, the programming process is always the same:
Each assembly language file is assembled into an 'object file'and the object files are linked with other object files to forman executable. A 'static library' is really nothing more thana collection of (probably related) object files. Applicationprogrammers generally make use of libraries for things likeI/O and math.
Assemblers you should know about include
- MASM, the Microsoft Assembler. It outputs OMF files (but Microsoft’s linker can convert them to win32 format). It supports a massive and clunky assembly language. Memory addressing is not intuitive. The directives required to set up a program make programming unpleasant.
- GAS, the GNU assember. This uses the rather ugly AT&T-style syntax so many people do not like it; however, you can configure it to use and understand the Intel-style. It was designed to be part of the back end of the GNU compiler collection (gcc).
- NASM, the 'Netwide Assembler.' It is free, small, and best of all it can output zillions of different types of object files. The language is much more sensible than MASM in many respects.
This document does not cover how to use all the differentassemblers; you need to read the documentation that comes withthem. We will, however, give step-by-step instructions andcomplete examples of all three of these assemblers for a few extremelysimple programs.
There are many object file formats. Some you should knowabout include
- OMF: used in DOS but has 32-bit extensions for Windows. Old.
- AOUT: used in early Linux and BSD variants
- COFF: 'Common object file format'
- Win, Win32: Microsoft’s version of COFF, not exactly the same! Replaces OMF.
- Win64: Microsoft’s format for Win64.
- ELF, ELF32: Used in modern 32-bit Linux and elsewhere
- ELF64: Used in 64-bit Linux and elsewhere
- macho32: NeXTstep/OpenStep/Rhapsody/Darwin/OS X 32-bit
- macho64: NeXTstep/OpenStep/Rhapsody/Darwin/OS X 64-bit
The NASM documentation has great descriptions of these.
You’ll need to get a linker that (1) understands the objectfile formats you produce, and (2) can write executables forthe operating systems you want to run code on. Some linkersout there include
- LINK.EXE, for Microsoft operating systems.
- ld, which exists on all Unix systems; Windows programmers get this in any gcc distribution.
Programming for Linux
Programming Using System Calls
64-bit Linux installations use the processor’s SYSCALL instruction to jump into the portionof memory where operating system services are stored. To use SYSCALL, first put the system callnumber in RAX, then the arguments, if any, in RDI, RSI, RDX, R10, R8, and R9, respectively.In our first example we will use system calls for writing to a file (call number 1) and exiting aprocess (call number 60). Here it is in the NASM assembly language:
Here’s the same program in gas:
Since gas is the 'native' assembler under Linux, assembling andlinking is automatic with gcc
, as explained in theprogram’s comments. If you just enter 'gcc hello.s
'then gcc
will assemble and then try to link with a Clibrary. You can suppress the link step with the -c
optionto gcc
, or do the assembly and linking in one stepby telling the linker not to use the C library with-nostdlib
.
System Calls in 32-bit Linux
There are some systems with 32-bit builds of Linux out there still. On these systems youinvoke operating systems services through an INT instruction, and use different registersfor system call arguments (specifically EAX for the call number and EBX, ECX, EDX, EDI, and ESIfor the arguments). Although it might be interesting to show some examples for historical reasons,this introduction is probably better kept short.
Programming with a C Library
Sometimes you might like to use your favorite C libraryfunctions in your assembly code. This should be trivial becausethe C library functions are all stored in a C library, such aslibc.a
. Technically the code is probably in a dynamiclibrary, like libc.so
, and libc.a
just hascalls into the dynamic library. Still, all we have todo is place calls to C functions in our assembly language program,and link with the static C library and we are set.
Before looking at an example, note that the C library alreadydefines _start
, which does some initialization,calls a function named main
, does some clean up,then calls the system function exit
! So if we linkwith a C library, all we have to do is define main
and end with a ret
instruction! Here is a simple examplein NASM, which illustrates calling puts
.
And the equivalent program in GAS:
Assembly Language Program To Read A String And Display The Image
The previous example shows that the first argument to a C function, if it’s an integer or pointer,goes in register RDI. Subsequent arguments go in RSI, RDX, RCX, R8, R9, and then subsequent arguments(which no sane programmer would ever use) will go 'on the stack' (more about this stackthing later). If you have floating point arguments, they’ll go in XMM0, XMM1, etc. There iseven quite a bit more to calling functions; we’ll see this later.
Programming for OS X
Rather than getting into OS X system calls, let’s just show the simple hello program using the C library.We’ll assume a 64-bit OS, and we’ll also assume you’ve installed gcc (usually obtained via downloading xcode).
There are some differences here! C library functions have underscores, and we had to say defaultrel
for some strange reason, which you can read about in the NASM documentation.
Programming for Win32
Win32 is the primary operating system API found in most ofMicrosoft’s 32-bit operating systems including Windows 9x,NT, 2000 and XP. We will follow the plan of the previous sectionand first look at programs that just use system calls andthen programs that use a C library.
For historical reference only.
Thesenotes are pretty old. I’ve never learned Win64.
Calling the Win32 API Directly
Win32 defines thousands of functions! The code for thesefunctions is spread out in many different dynamic libraries, butthe majority of them are in KERNEL32.DLL
, USER32.DLL
and GDI32.DLL
(which exist on all Windows installations).The interrupt to execute system calls on the x86 processoris hex 2E, with EAX containing the system call number andEDX pointing to the parameter table in memory. However, according toz0mbie, theactually system call numbers are not consistent across differentoperating systems, so, to write portable code you should stick tothe API calls in the various system DLLs.
Here is the 'Hello, World' program in NASM, using only Win32calls.
Here you can see that the Win32 calls we are using are
and parameters are passed to these calls on the stack.The comments instruct us to assemble into an object formatof 'win32' (not 'coff'!) then link with the linker ld
.Of course you can use any linker you want, but ld
comeswith gcc
and you can download a whole Win32 portof gcc
for free. We pass thestarting address to the linker, and specify the static librarylibkernel32.a
to link with. This static libraryis part of the Win32 gcc
distribution, and itcontains the right calls into the system DLLs.
Assembly Language Program To Read A String And Display The Table
The gas version of this program looks very similar:
In fact the differences between the two programs are really onlysyntactic. Another minor point is that gas doesn’t really careif you define external systems with some sort of 'extern' directiveor not.
As in the NASM version, we’ve specified our entry point, andwill be passing it to the linker in the -e option. To assemblethis code, do
The -c option is important! It tells gcc to assemble but notlink. Without the -c option, gcc will try to link theobject file with a C runtime library. Since we are not usinga C runtime library, and in fact are specifying our own startingpoint, and cleaning up ourselves with ExitProcess
wedefinitely want to link ourselves. The linking step is thesame as the NASM example; the only difference is that gccproduces win32 object files with extension .o rather than .obj.
If you really want to pay a vendor for an assembler and linkeryou can use Microsoft’s MASM assembler. Anything lessthan version 6.14 will be extremely painful to use.Here is the version of the hello
program in MASM
The processor (.386P) and model (.model) directivesare an annoyance, but they have to be there and the processordirective must precede the model directive or the assembler willthink the processor is running in 16-bit mode (*sigh*
).As before we have to specify an entry point and pass it tothe linker. Assemble with
The /c
option is required since ml
will try to link.Not only is the MASM assembler, ml
, not free, but neither isMicrosoft’s linker, link.exe
, nor are static versions of theWin32 libraries, such as kernel32.lib
. After you buy thoseyou link your code with
To get this to work, kernel32.lib
needs to be in a knownlibrary path or additional options must be passed to the linker.You might find the /subsystem
option interesting; leave itout to see a ridiculous error message when running the linkedexecutable (at least under Win9x).
Most of MASM’s syntactic weirdness, like using the 'offset'keyword to get the address of a variable are not present inNASM. While NASM is probably gaining popularity, there is far moreMASM code out there, and it is a good idea to haveat least a passing acquaintance with MASM, since mostpublications use it. It is the closest thingto a 'standard' x86 assembly language there is.
Using a C Runtime Library for Win32 Programming
As under Linux, using a C runtime library makes it veryeasy to write simple assembly language programs. Here isone in NASM:
The same program in gas looks like this:
Note you can assemble and link with
For the MASM version of this program, you can go purchase CRuntime Libraries from Microsoft as well.There are many versions of the library, but for singlethreaded programs, libc.lib
is fine. Hereis the powers program in MASM:
When linking with libc.lib you get nice linker defaults. Toassemble and link:
You’ll have to make sure the linker knows where to find libc.libby setting some environment variables, of course, but youget the idea.
OpenGL Programming in NASM for Win32
For fun, here is a complete assembly language program that implements an OpenGLapplication running under GLUT on Windows systems:
Programming for DOS
Both MASM and NASM can create DOS executables. DOS is a primitiveoperating system (indeed, many people, perhaps correctly, refuseto call it an operating system), which runs in real mode only.Real mode addresses are 20-bit values written in the formSEGMENT:OFFSET where the segment and offset are each 16-bitswide and the physical address is SEGMENT * 16 + OFFSET.
A DOS program is a collection of segments. When the programis loaded, DS:0 and ES:0 points to a 256-byte section of memorycalled the program segment prefix and this is immediately followedby the segments of the program. CS:0 will point to the code segmentand SS:0 to the stack segment. SP will be loaded with the size ofthe stack specified by the programmer, which is perfect becauseon the x86 a PUSH instruction decrements the stack pointer andthen moves the pushed value into the memory addressed by SS:SP.The length of the command line argument string is placed in thebyte at offset 80h of the prefix and the actual argument stringbegins at offset 81h.
Here is a simple DOS program to echo the command line argumentstring:
Note with the MASM assembler you have to place the .model directivebefore the processor directive to make the processor use 16-bit moderequired for DOS.
Note that all 'operating system services' such as input/outputare accessible through the processor’s interrupt instructionso there is no need to link your program to a special library.Of course if you wanted to link to a 16-bit C runtime libraryyou certainly can.
The echo program defines only a code and stack segment; anexample of a program with a programmer-defined data segment is:
Although DOS has been obsolete for many years, a brief studyof DOS systems and the x86 real-addressing mode is somewhatinteresting. First, real-mode addresses correspond to real,physical memory, so one can watch exactly what is happeningin the machine very easily with a good debugger. In fact,most embedded microprocessors work in a kind of 'real mode.'Less than 1% of microprocessors run desktop PCs, serversand workstations; most are simple embedded processors.Finally a lot of DOS applications still exist, so it mightbe useful to know what kind of technology underlies it all.
Writing Optimized Code
Assembly language programmers and compiler writers should takegreat care in producing efficient code. This requires a fairlydeep understanding of the x86 architecture, especially thebehavior of the cache(s), pipelines and alignment bias. Thesespecifics are well beyond the scope of this little document,but an excellent place to begin your study of this materialis Agner Fog’s Optimization Guideor even Intel’s.
Differences between NASM, MASM, and GAS
The complete syntactic specification of each assembly language canbe found elsewhere, but you can learn 99% of what you need toknow by looking at a comparison table:
Assembly Language Program To Read A String And Display The Number
Operation | NASM | MASM | GAS |
---|---|---|---|
Move contents of esi into ebx | mov ebx, esi | movl %esi, %ebx | |
Move contents of si into dx | mov dx, si | movw %si, %dx | |
Clear the eax register | xor eax, eax | xorl %eax, %eax | |
Move immediate value 10 into register al | mov al, 10 | movb $10, %al | |
Move contents of address 10 into register ecx | mov ecx, [10] | I DON’T KNOW | movl 10, %ecx |
Move contents of variable dog into register eax | mov eax, [dog] | mov eax, dog | movl dog, %eax |
Move address of variable dog into register eax | mov eax, dog | I DON’T KNOW | movl $dog, %eax |
Move immediate byte value 10 into memory pointed to by edx | mov byte [edx], 10 | mov byte ptr [edx], 10 | movb $10, (%edx) |
Move immediate 16-bit value 10 into memory pointed to by edx | mov word [edx], 10 | mov word ptr [edx], 10 | movw $10, (%edx) |
Move immediate 32-bit value 10 into memory pointed to by edx | mov dword [edx], 10 | mov dword ptr [edx], 10 | movl $10, (%edx) |
Compare eax to the contents of memory 8 bytes past the cell pointed to by ebp | cmp eax, [ebp+8] | cmpl $8(%ebp), %eax | |
Add into esi the value in memory ecx quadwords past the cell pointed to by eax | add esi, [eax+ecx*8] | addl (%eax,%ecx,8), %esi | |
Add into esi the value in memory ecx doublewords past 128 bytes past the cell pointed to by eax | add esi, [eax+ecx*4+128] | addl $128(%eax,%ecx,4), %esi | |
Add into esi the value in memory ecx doublewords past eax bytes past the beginning of the variable named array | add esi, [eax+ecx*4+array] | addl array(%eax,%ecx,4), %esi | |
Add into esi the value in memory ecx words past the beginning of the variable named array | add esi, [ecx*2+array] | addl array(,%ecx,2), %esi | |
Move the immediate value 4 into the memory cell pointed to by eax using selector fs | mov byte [fs:eax], 4 | mov byte ptr fs:eax, 4 | movb $4, %fs:(%eax) |
Jump into another segment | ? | jump far S:O | ljmp $S, $O |
Call to another segment | ? | call far S:O | lcall $S, $O |
Return from an intersegment call | retf V | ret far V | lret $V |
Sign-extend al into ax | cbw | cbtw | |
Sign-extend ax into eax | cwde | cwtl | |
Sign-extend ax into dx:ax | cwd | cwtd | |
Sign-extend eax into edx:eax | cdq | cltd | |
Sign-extend bh into si | movsx si, bh | movsbw %bh, %si | |
Sign-extend bh into esi | movsx esi, bh | movsbl %bh, %esi | |
Sign-extend cx into esi | movsx esi, cx | movswl %cx, %esi | |
Zero-extend bh into si | movzx si, bh | movzbw %bh, %si | |
Zero-extend bh into esi | movzx esi, bh | movzbl %bh, %esi | |
Zero-extend cx into esi | movzx esi, cx | movzwl %cx, %esi | |
100 doublewords, all initialized to 8192 | times 100 dd 8192 | dd 100 dup (8192) | I DON’T KNOW |
Reserve 64 bytes of storage | resb 64 | db 64 dup (?) | .space 64 |
Hello World | db 'Hello, World' | .ascii 'Hello, World' | |
Hello World with a newline, and zero-terminated | db 'Hello, World', 10, 0 | .asciz 'Hello, Worldn' |
Good to know:
Assembly Language Program To Read A String And Display Key
- NASM and MASM use what is sometimes called the Intel syntax, while GAS uses what is called the AT&T syntax.
- GAS uses % to prefix registers
- GAS is source(s) first, destination last; MASM and NASM go the other way.
- GAS denotes operand sizes on instructions (with b, w, l suffixes), rather than on operands
- GAS uses $ for immediates, but also for addresses of variables.
- GAS puts rep/repe/repne/repz/repnz prefixes on separate lines from the instructions they modify
- MASM tries to simplify things for the programmer but makes headaches instead: it tries to 'remember' segments, variable sizes and so on. The result is a requirement for stupid ASSUME directives, and the inability to tell what an instrction does by looking at it (you have to go look for declarations; e.g.
dw
vs.equ
). - MASM writes FPU registers as ST(0), ST(1), etc.
- NASM treats labels case-sensitively; MASM is case-insensitive.
.stack
.data
message db 'My First Assembly Language Program$'
.code
main proc
mov ax, seg Message
;moves the SEGMENT that 'Message' is in into AX
;equivalent to MOV ax,@data
mov ds,ax
;moves ax into ds (ds=ax)
;you can not do this ->mov ds, seg Message
mov dx,offset Message
;moves the OFFSET of 'Message' into DX
;equivalent to LEA dx,Message
mov ah,9
;function 9 of DOS interrupt 21h prints a string
int 21h
;terminates with a '$'
mov ax,4c00h
;returns control to DOS
int 21h
;must be here! If not, Program will crash!
main endp
end main