Title: asm and C
1asm and C
2public and external
- public, in an assembly module, declares that a
symbol defined in this module should be made
available (by linker) to other modules being
linked. - extern indicates that a symbol used in this
module is not defined here, but in another module
3main.cpp (Borland C)
- // main.cpp
- // Calls the external LongRandom function,
written in - // assembly language, that returns an unsigned
32-bit - // random integer. Compile in the Large memory
model. - include ltiostream.hgt
- extern "C" unsigned long LongRandom()
- //"C" indicates to the compiler not to use name
mangling but standard C naming - //long will return long (32 bit) int in dxax
- const int ARRAY_SIZE 500
- int main()
-
- // Allocate array storage and fill with 32-bit
- // unsigned random integers.
- unsigned long rArray new unsigned
longARRAY_SIZE
4asm proc longrandom
- LongRandom procedure module (longrand.asm)
- .model large
- .386
- Public _LongRandom
- .data
- seed dd 12345678h//seed should be odd, not even
- Return an unsigned pseudo-random 32-bit integer
- in DXAX,in the range 0 - FFFFFFFFh.
- .code
- _LongRandom proc far, C
- mov eax, 214013
- mul seed
- xor edx,edx
- add eax, 2531011
- mov seed, eax save the seed for the
next call - shld edx,eax,16 copy upper 16 bits of
EAX to DX
5longrand.exe
- text examples come with (some) compiled cpp and
assembled asm examples. - you would need to find a borland c compiler to
undertake this work. - there is a free c compiler (commandline only no
ide) available from inprise (borland) - you would link the two obj files to create an exe
6Free compiler from borland
- Link for compilerhttp//community.borland.com/art
icle/0,1410,20633,00.html
7IDEs available for Borland compiler
8IDE continued SoftwareDave site
- You can easily integrate borland C compiler
with textpad, also.
9(some of the) output
- C\MASM615\EXAMPLES\CH12\BORLAN1\LONGRANDgtlongran
d - 3018423131,1530878130,3423460525,3768712380,153659
6111,3080048918,405865345,3338 - 983488,2101941763,875374778,3701378197,761367812,1
42804919,3419349918,218704873, - 3429891848,1470939563,563267010,3913012605,2845790
796,1275647967,4244656934,4140 - 39377,341437136,1709710931,3514126282,2757121893,1
43223956,2904402183,3569909678 - ,1119967161,2589637528,2108869627,1764615890,28585
94893,1329724380,2363169583,37 - 30491702,3727334177,2285801824,3123210915,34546429
06,2824439349,1633624100,21641 - 82615,2533248958,3079939977,2860878888,508074571,3
173628898,305623837,3714775404 - ,3194643071,781071174,3555499249,887344112,1198979
827,3041081834,1769806085,1231 - 267764,2476963751,402232270,3202784089,3603001528,
804990107,2917090546,330242029 - ,2403027708,4082347471,1774424406,1769521857,53232
2944,25218883,2692414714,32352 - 54229,3377988420,248030455,243485662,2556277545,87
4473800,4153901803,3773268482, - 1644077245,1595142284,7601439,3311657830,380135336
1,3514039568,1379067795,117086 - 3114,2948164261,1899836116,2255181383,4070864878,1
071542009,2733667800,147918777 - 1,555447058,1083903373,2526407196,3437777007,10753
25302,658733665,3858822048,177 - 3814755,145301274,800860533,3897833060,1221102487,
228988926,1032703689,159000740 - 0,587299723,1855199266,1396268637,1587689388,27188
03903,2982765446,2479623217,26 - 26846256,2391008307,164724266,45304901,2099121652,
2925348071,2316381198,19766196 - 73,2389691128,1739136475,246051122,1842254637,1331
288380,2072052495,3684733334,3
10what should c do, what should asm do?
- C should do things like i/o and real computations
- asm should handle low level operations including
graphics--- activities which might involve
rom-bios or dos function calls
11cpp for read sector example
- // SectorMain.cpp - Calls ReadSector Procedure
- include ltiostream.hgt
- include ltconio.hgt
- include ltstdlib.hgt
- const int SECTOR_SIZE 512
- extern "C" ReadSector( char buffer, long
startSector, - int driveNum, int numSectors )
- void DisplayBuffer( const char buffer, long
startSector, - int numSectors )
- int n 0
- long last startSector numSectors
- for(long sNum startSector sNum lt last
sNum) -
- cout ltlt "\nSector " ltlt sNum
- ltlt " ---------------------------"
- ltlt "-----------------------------\n"
- for(int i 0 i lt SECTOR_SIZE i)
-
12main.cpp
- int main()
-
- char buffer
- long startSector
- int driveNum
- int numSectors
- system("CLS")
- cout ltlt "Sector display program.\n\n"
- ltlt "Enter drive number 1A, 2B, 3C, 4D,
5E,... " - cin gtgt driveNum
- cout ltlt "Starting sector number to read "
- cin gtgt startSector
- cout ltlt "Number of sectors to read "
- cin gtgt numSectors
- buffer new charnumSectors SECTOR_SIZE
- cout ltlt "\n\nReading sectors " ltlt startSector
ltlt " - " - ltlt (startSector numSectors) ltlt " from
Drive "
13asm part of reading sectors
- TITLE Reading Disk Sectors (ReadSec.asm)
- The ReadSector procedure is called from a
16-bit - Real-mode application written in Borland C
5.01. - It can read FAT12, FAT16, and FAT32 disks under
- MS-DOS, and Windows 95/98/Me.
- Last update 12/5/01
- Public _ReadSector
- .model small
- .386
- DiskIO STRUC
- strtSector DD ? starting sector number
- nmSectors DW 1 number of sectors
- bufferOfs DW ? buffer offset
- bufferSeg DW ? buffer segment
- DiskIO ENDS
14read sectors continued
- .code
- -------------------------------------------------
--------- - _ReadSector PROC NEAR C
- ARG bufferPtrWORD, startSectorDWORD,
driveNumberWORD, \ - numSectorsWORD
-
- Read n sectors from a specified disk drive.
- Receives pointer to buffer that will hold the
sector, - data, starting sector number, drive number,
- and number of sectors.
- Returns nothing
- -------------------------------------------------
--------- - enter 0,0
- pusha
- mov eax,startSector
- mov diskStruct.strtSector,eax
- mov ax,numSectors
- mov diskStruct.nmSectors,ax
- mov ax,bufferPtr
15readsectors.exe
16Some VC examples
- I havent run these yet although the text has
screen shots. - The same thing could have been done in another
version of C
17addmain.cpp
- // Addem Main Program (AddMain.cpp)
- include ltiostream.hgt
- extern "C" int addem(int p1, int p2, int p3)
- int main()
-
- int total addem( 10, 15, 25 )
- cout ltlt "Total " ltlt total ltlt endl//will just
display total - return 0
-
18addem.cpp (note how the module is named in C
with underscore)
- title The addem Subroutine (addem.asm)
- This subroutine links to Visual C 6.0.
- .386P
- .model flat
- public _addem
- .code
- _addem proc near
- push ebp
- mov ebp,esp
- mov eax,ebp16 first argument
- add eax,ebp12 second argument
- add eax,ebp8 third argument
- pop ebp
- ret
- _addem endp
- end
19arraysum in C
- void MySub()
-
- char A 'A'
- int B 10
- char name20
- name0 'B'
- double c 1.2
-
- int ArraySum( int array, int count )
-
- int sum 0
- for(int i 0 i lt count i)
- sum arrayi
-
- return sum
-
20the array sum.asm showing name mangling
- TITLE D\Kip\AsmBook4\Examples\HLL_Linking\Visual
CPP\ArraySum\ArraySum.cpp - .386P
- include listing.inc
- if _at_Version gt 510
- .model FLAT
- else
- _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
- _TEXT ENDS
- _DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
- _DATA ENDS
- CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
- CONST ENDS
- _BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
- _BSS ENDS
- _TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
- _TLS ENDS
- COMDAT ?MySub_at__at_YAXXZ
- _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
- _TEXT ENDS
21the array sum.asm showing name mangling
- PUBLIC ?ArraySum_at__at_YAHQAHH_at_Z ArraySum
- COMDAT ?ArraySum_at__at_YAHQAHH_at_Z
- _TEXT SEGMENT
- _array 8
- _count 12
- ?ArraySum_at__at_YAHQAHH_at_Z PROC NEAR ArraySum,
COMDAT - Line 16
- mov edx, DWORD PTR _countesp-4
- xor eax, eax
- test edx, edx
- jle SHORT L279
- mov ecx, DWORD PTR _arrayesp-4
- push esi
- L277
- Line 17
- mov esi, DWORD PTR ecx
- add ecx, 4
- add eax, esi
- dec edx
22the example comes with an exe (no output)
23in line asm example
- pragma warning (disable4101)
- // disable warning about unreferenced local
variables - include ltiostreamgt
- int main()
-
- stdcout ltlt "(this program generates no
output)\n\n" - struct Package
- long originZip // 4
- long destinationZip // 4
- float shippingPrice // 4
-
-
- char myChar
- bool myBool
- short myShort
- int myInt
24inline example continued
- __asm
- mov eax,myPackage.destinationZip
- mov eax,LENGTH myInt // 1
- mov eax,LENGTH myLongArray // 10
- mov eax,TYPE myChar // 1
- mov eax,TYPE myBool // 1
- mov eax,TYPE myShort // 2
- mov eax,TYPE myInt // 4
- mov eax,TYPE myLong // 4
- mov eax,TYPE myFloat // 4
- mov eax,TYPE myDouble // 8
- mov eax,TYPE myPackage // 12
- mov eax,TYPE myLongDouble // 8
- mov eax,TYPE myLongArray // 4
- mov eax,SIZE myLong // 4
- mov eax,SIZE myPackage // 12
25C and inline asm
- C allows the use of inline asm
- I could not find an exe for this example (and I
didnt load/run it in VC)
26findarray example-the asm proc
- title The FindArray Procedure (scasd.asm)
- This version uses hand-optimized assembly
- language code with the SCASD instruction.
- .386P
- .model flat
- public _FindArray
- true 1
- false 0
- Stack parameters
- srchVal equ ebp08
- arrayPtr equ ebp12
- count equ ebp16
- .code
- _FindArray proc near
- push ebp
27findarray example-the cpp proc
- // findArr.cpp
- include "findarr.h"
- bool FindArray2( long searchVal, long array,
- long count )
-
- for(int i 0 i lt count i)
- if( searchVal arrayi )
- return true
- return false
-
28the header file declares the external procs
- // findarr.h
- extern "C"
- bool FindArray( long n, long array, long count
) - // Assembly language version
- bool FindArray2( long n, long array, long count
) - // CPP version
29findarray main
- // main.cpp - Testing the FindArray subroutine.
- include ltstdlib.hgt
- include ltiostream.hgt
- include "findarr.h"
- int main()
-
- const unsigned ARRAY_SIZE 10000
- long arrayARRAY_SIZE
-
- // Fill the array with pseudorandom integers.
- for(unsigned i 0 i lt ARRAY_SIZE i)
-
- arrayi rand()
- // cout ltlt arrayi ltlt "," // display
each value -
- cout ltlt "\n\n"
-
- long searchVal
30findarray
- I didnt compile this VC example to see the
comparison