convert.txt 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. Specifically: for use with gcc with its libraries and gdb
  2. Specifically: simple nasm syntax using "C" literals
  3. Specifically: showing an equivalent "C" program
  4. Generally, for Linux and possibly other Unix on Intel
  5. Generally, not using 8-bit or 16-bit or 32-bit for anything
  6. Contents
  7. Makefile for samples shown below
  8. hello_64.asm simple Hello World program
  9. printf1_64.asm basic calling printf
  10. printf2_64.asm more types for printf
  11. intarith_64.asm simple integer arithmetic
  12. fltarith_64.asm simple floating point arithmetic
  13. fib_64l.asm Print 64-bit fibinachi numbers
  14. fib_64m.asm Print more like C
  15. loopint_64.asm simple loop
  16. testreg_64.asm use rax, eax, ax, ah, al
  17. shift_64.asm shifting
  18. ifint_64.asm if then else
  19. intlogic_64.asm and, or, xor, not
  20. horner_64.asm Horner method int and double
  21. call1_64.asm use address of array
  22. hello_64.asm first sample program
  23. The nasm source code is hello_64.asm
  24. The result of the assembly is hello_64.lst
  25. Running the program produces output hello_64.out
  26. This program demonstrates basic text output to a file and screen.
  27. Call is made to C printf
  28. ; hello_64.asm print a string using printf
  29. ; Assemble: nasm -f elf64 -l hello_64.lst hello_64.asm
  30. ; Link: gcc -m64 -o hello_64 hello_64.o
  31. ; Run: ./hello_64 > hello_64.out
  32. ; Output: cat hello_64.out
  33. ; Equivalent C code
  34. ; // hello.c
  35. ; #include <stdio.h>
  36. ; int main()
  37. ; {
  38. ; char msg[] = "Hello world\n";
  39. ; printf("%s\n",msg);
  40. ; return 0;
  41. ; }
  42. ; Declare needed C functions
  43. extern printf ; the C function, to be called
  44. section .data ; Data section, initialized variables
  45. msg: db "Hello world", 0 ; C string needs 0
  46. fmt: db "%s", 10, 0 ; The printf format, "\n",'0'
  47. section .text ; Code section.
  48. global main ; the standard gcc entry point
  49. main: ; the program label for the entry point
  50. push rbp ; set up stack frame, must be alligned
  51. mov rdi,fmt
  52. mov rsi,msg
  53. mov rax,0 ; or can be xor rax,rax
  54. call printf ; Call C function
  55. pop rbp ; restore stack
  56. mov rax,0 ; normal, no error, return value
  57. ret ; return
  58. printf1_64.asm basic calling printf
  59. The nasm source code is printf1_64.asm
  60. The result of the assembly is printf1_64.lst
  61. The equivalent "C" program is printf1_64.c
  62. Running the program produces output printf1_64.out
  63. This program demonstrates basic use of "C" library function printf.
  64. The equivalent "C" code is shown as comments in the assembly language.
  65. ; printf1_64.asm print an integer from storage and from a register
  66. ; Assemble: nasm -f elf64 -l printf1_64.lst printf1_64.asm
  67. ; Link: gcc -o printf1_64 printf1_64.o
  68. ; Run: ./printf1_64
  69. ; Output: a=5, rax=7
  70. ; Equivalent C code
  71. ; /* printf1.c print a long int, 64-bit, and an expression */
  72. ; #include <stdio.h>
  73. ; int main()
  74. ; {
  75. ; long int a=5;
  76. ; printf("a=%ld, rax=%ld\n", a, a+2);
  77. ; return 0;
  78. ; }
  79. ; Declare external function
  80. extern printf ; the C function, to be called
  81. SECTION .data ; Data section, initialized variables
  82. a: dq 5 ; long int a=5;
  83. fmt: db "a=%ld, rax=%ld", 10, 0 ; The printf format, "\n",'0'
  84. SECTION .text ; Code section.
  85. global main ; the standard gcc entry point
  86. main: ; the program label for the entry point
  87. push rbp ; set up stack frame
  88. mov rax,[a] ; put "a" from store into register
  89. add rax,2 ; a+2 add constant 2
  90. mov rdi,fmt ; format for printf
  91. mov rsi,[a] ; first parameter for printf
  92. mov rdx,rax ; second parameter for printf
  93. mov rax,0 ; no xmm registers
  94. call printf ; Call C function
  95. pop rbp ; restore stack
  96. mov rax,0 ; normal, no error, return value
  97. ret ; return
  98. printf2_64.asm more types with printf
  99. The nasm source code is printf2_64.asm
  100. The result of the assembly is printf2_64.lst
  101. The equivalent "C" program is printf2_64.c
  102. Running the program produces output printf2_64.out
  103. This program demonstrates general use of "C" library function printf.
  104. The equivalent "C" code is shown as comments in the assembly language.
  105. ; printf2_64.asm use "C" printf on char, string, int, long int, float, double
  106. ;
  107. ; Assemble: nasm -f elf64 -l printf2_64.lst printf2_64.asm
  108. ; Link: gcc -m64 -o printf2_64 printf2_64.o
  109. ; Run: ./printf2_64 > printf2_64.out
  110. ; Output: cat printf2_64.out
  111. ;
  112. ; A similar "C" program printf2_64.c
  113. ; #include <stdio.h>
  114. ; int main()
  115. ; {
  116. ; char char1='a'; /* sample character */
  117. ; char str1[]="mystring"; /* sample string */
  118. ; int len=9; /* sample string */
  119. ; int inta1=12345678; /* sample integer 32-bit */
  120. ; long int inta2=12345678900; /* sample long integer 64-bit */
  121. ; long int hex1=0x123456789ABCD; /* sample hexadecimal 64-bit*/
  122. ; float flt1=5.327e-30; /* sample float 32-bit */
  123. ; double flt2=-123.4e300; /* sample double 64-bit*/
  124. ;
  125. ; printf("printf2_64: flt2=%e\n", flt2);
  126. ; printf("char1=%c, srt1=%s, len=%d\n", char1, str1, len);
  127. ; printf("char1=%c, srt1=%s, len=%d, inta1=%d, inta2=%ld\n",
  128. ; char1, str1, len, inta1, inta2);
  129. ; printf("hex1=%lX, flt1=%e, flt2=%e\n", hex1, flt1, flt2);
  130. ; return 0;
  131. ; }
  132. extern printf ; the C function to be called
  133. SECTION .data ; Data section
  134. ; format strings for printf
  135. fmt2: db "printf2: flt2=%e", 10, 0
  136. fmt3: db "char1=%c, str1=%s, len=%d", 10, 0
  137. fmt4: db "char1=%c, str1=%s, len=%d, inta1=%d, inta2=%ld", 10, 0
  138. fmt5: db "hex1=%lX, flt1=%e, flt2=%e", 10, 0
  139. char1: db 'a' ; a character
  140. str1: db "mystring",0 ; a C string, "string" needs 0
  141. len: equ $-str1 ; len has value, not an address
  142. inta1: dd 12345678 ; integer 12345678, note dd
  143. inta2: dq 12345678900 ; long integer 12345678900, note dq
  144. hex1: dq 0x123456789ABCD ; long hex constant, note dq
  145. flt1: dd 5.327e-30 ; 32-bit floating point, note dd
  146. flt2: dq -123.456789e300 ; 64-bit floating point, note dq
  147. SECTION .bss
  148. flttmp: resq 1 ; 64-bit temporary for printing flt1
  149. SECTION .text ; Code section.
  150. global main ; "C" main program
  151. main: ; label, start of main program
  152. push rbp ; set up stack frame
  153. fld dword [flt1] ; need to convert 32-bit to 64-bit
  154. fstp qword [flttmp] ; floating load makes 80-bit,
  155. ; store as 64-bit
  156. mov rdi,fmt2
  157. movq xmm0, qword [flt2]
  158. mov rax, 1 ; 1 xmm register
  159. call printf
  160. mov rdi, fmt3 ; first arg, format
  161. mov rsi, [char1] ; second arg, char
  162. mov rdx, str1 ; third arg, string
  163. mov rcx, len ; fourth arg, int
  164. mov rax, 0 ; no xmm used
  165. call printf
  166. mov rdi, fmt4 ; first arg, format
  167. mov rsi, [char1] ; second arg, char
  168. mov rdx, str1 ; third arg, string
  169. mov rcx, len ; fourth arg, int
  170. mov r8, [inta1] ; fifth arg, inta1 32->64
  171. mov r9, [inta2] ; sixth arg, inta2
  172. mov rax, 0 ; no xmm used
  173. call printf
  174. mov rdi, fmt5 ; first arg, format
  175. mov rsi, [hex1] ; second arg, char
  176. movq xmm0, qword [flttmp] ; first double
  177. movq xmm1, qword [flt2] ; second double
  178. mov rax, 2 ; 2 xmm used
  179. call printf
  180. pop rbp ; restore stack
  181. mov rax, 0 ; exit code, 0=normal
  182. ret ; main returns to operating system
  183. intarith_64.asm simple 64-bit integer arithmetic
  184. The nasm source code is intarith_64.asm
  185. The result of the assembly is intarith_64.lst
  186. The equivalent "C" program is intarith_64.c
  187. Running the program produces output intarith_64.out
  188. This program demonstrates basic integer arithmetic add, subtract,
  189. multiply and divide.
  190. The equivalent "C" code is shown as comments in the assembly language.
  191. ; intarith_64.asm show some simple C code and corresponding nasm code
  192. ; the nasm code is one sample, not unique
  193. ;
  194. ; compile: nasm -f elf64 -l intarith_64.lst intarith_64.asm
  195. ; link: gcc -m64 -o intarith_64 intarith_64.o
  196. ; run: ./intarith_64 > intarith_64.out
  197. ;
  198. ; the output from running intarith_64.asm and intarith.c is:
  199. ; c=5 , a=3, b=4, c=5
  200. ; c=a+b, a=3, b=4, c=7
  201. ; c=a-b, a=3, b=4, c=-1
  202. ; c=a*b, a=3, b=4, c=12
  203. ; c=c/a, a=3, b=4, c=4
  204. ;
  205. ;The file intarith.c is:
  206. ; /* intarith.c */
  207. ; #include <stdio.h>
  208. ; int main()
  209. ; {
  210. ; long int a=3, b=4, c;
  211. ; c=5;
  212. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=5 ", a, b, c);
  213. ; c=a+b;
  214. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=a+b", a, b, c);
  215. ; c=a-b;
  216. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=a-b", a, b, c);
  217. ; c=a*b;
  218. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=a*b", a, b, c);
  219. ; c=c/a;
  220. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=c/a", a, b, c);
  221. ; return 0;
  222. ; }
  223. extern printf ; the C function to be called
  224. %macro pabc 1 ; a "simple" print macro
  225. section .data
  226. .str db %1,0 ; %1 is first actual in macro call
  227. section .text
  228. mov rdi, fmt4 ; first arg, format
  229. mov rsi, .str ; second arg
  230. mov rdx, [a] ; third arg
  231. mov rcx, [b] ; fourth arg
  232. mov r8, [c] ; fifth arg
  233. mov rax, 0 ; no xmm used
  234. call printf ; Call C function
  235. %endmacro
  236. section .data ; preset constants, writable
  237. a: dq 3 ; 64-bit variable a initialized to 3
  238. b: dq 4 ; 64-bit variable b initializes to 4
  239. fmt4: db "%s, a=%ld, b=%ld, c=%ld",10,0 ; format string for printf
  240. section .bss ; uninitialized space
  241. c: resq 1 ; reserve a 64-bit word
  242. section .text ; instructions, code segment
  243. global main ; for gcc standard linking
  244. main: ; label
  245. push rbp ; set up stack
  246. lit5: ; c=5;
  247. mov rax,5 ; 5 is a literal constant
  248. mov [c],rax ; store into c
  249. pabc "c=5 " ; invoke the print macro
  250. addb: ; c=a+b;
  251. mov rax,[a] ; load a
  252. add rax,[b] ; add b
  253. mov [c],rax ; store into c
  254. pabc "c=a+b" ; invoke the print macro
  255. subb: ; c=a-b;
  256. mov rax,[a] ; load a
  257. sub rax,[b] ; subtract b
  258. mov [c],rax ; store into c
  259. pabc "c=a-b" ; invoke the print macro
  260. mulb: ; c=a*b;
  261. mov rax,[a] ; load a (must be rax for multiply)
  262. imul qword [b] ; signed integer multiply by b
  263. mov [c],rax ; store bottom half of product into c
  264. pabc "c=a*b" ; invoke the print macro
  265. diva: ; c=c/a;
  266. mov rax,[c] ; load c
  267. mov rdx,0 ; load upper half of dividend with zero
  268. idiv qword [a] ; divide double register edx rax by a
  269. mov [c],rax ; store quotient into c
  270. pabc "c=c/a" ; invoke the print macro
  271. pop rbp ; pop stack
  272. mov rax,0 ; exit code, 0=normal
  273. ret ; main returns to operating system
  274. fltarith_64.asm simple floating point arithmetic
  275. The nasm source code is fltarith_64.asm
  276. The result of the assembly is fltarith_64.lst
  277. The equivalent "C" program is fltarith_64.c
  278. Running the program produces output fltarith_64.out
  279. This program demonstrates basic floating point add, subtract,
  280. multiply and divide.
  281. The equivalent "C" code is shown as comments in the assembly language.
  282. ; fltarith_64.asm show some simple C code and corresponding nasm code
  283. ; the nasm code is one sample, not unique
  284. ;
  285. ; compile nasm -f elf64 -l fltarith_64.lst fltarith_64.asm
  286. ; link gcc -m64 -o fltarith_64 fltarith_64.o
  287. ; run ./fltarith_64 > fltarith_64.out
  288. ;
  289. ; the output from running fltarith and fltarithc is:
  290. ; c=5.0, a=3.000000e+00, b=4.000000e+00, c=5.000000e+00
  291. ; c=a+b, a=3.000000e+00, b=4.000000e+00, c=7.000000e+00
  292. ; c=a-b, a=3.000000e+00, b=4.000000e+00, c=-1.000000e+00
  293. ; c=a*b, a=3.000000e+00, b=4.000000e+00, c=1.200000e+01
  294. ; c=c/a, a=3.000000e+00, b=4.000000e+00, c=4.000000e+00
  295. ; a=i , a=8.000000e+00, b=1.600000e+01, c=1.600000e+01
  296. ; a<=b , a=8.000000e+00, b=1.600000e+01, c=1.600000e+01
  297. ; b==c , a=8.000000e+00, b=1.600000e+01, c=1.600000e+01
  298. ;The file fltarith.c is:
  299. ; #include <stdio.h>
  300. ; int main()
  301. ; {
  302. ; double a=3.0, b=4.0, c;
  303. ; long int i=8;
  304. ;
  305. ; c=5.0;
  306. ; printf("%s, a=%e, b=%e, c=%e\n","c=5.0", a, b, c);
  307. ; c=a+b;
  308. ; printf("%s, a=%e, b=%e, c=%e\n","c=a+b", a, b, c);
  309. ; c=a-b;
  310. ; printf("%s, a=%e, b=%e, c=%e\n","c=a-b", a, b, c);
  311. ; c=a*b;
  312. ; printf("%s, a=%e, b=%e, c=%e\n","c=a*b", a, b, c);
  313. ; c=c/a;
  314. ; printf("%s, a=%e, b=%e, c=%e\n","c=c/a", a, b, c);
  315. ; a=i;
  316. ; b=a+i;
  317. ; i=b;
  318. ; c=i;
  319. ; printf("%s, a=%e, b=%e, c=%e\n","c=c/a", a, b, c);
  320. ; if(ab ", a, b, c);
  321. ; if(b==c)printf("%s, a=%e, b=%e, c=%e\n","b==c ", a, b, c);
  322. ; else printf("%s, a=%e, b=%e, c=%e\n","b!=c ", a, b, c);
  323. ; return 0;
  324. ; }
  325. extern printf ; the C function to be called
  326. %macro pabc 1 ; a "simple" print macro
  327. section .data
  328. .str db %1,0 ; %1 is macro call first actual parameter
  329. section .text
  330. ; push onto stack backwards
  331. mov rdi, fmt ; address of format string
  332. mov rsi, .str ; string passed to macro
  333. movq xmm0, qword [a] ; first floating point in fmt
  334. movq xmm1, qword [b] ; second floating point
  335. movq xmm2, qword [c] ; third floating point
  336. mov rax, 3 ; 3 floating point arguments to printf
  337. call printf ; Call C function
  338. %endmacro
  339. section .data ; preset constants, writable
  340. a: dq 3.0 ; 64-bit variable a initialized to 3.0
  341. b: dq 4.0 ; 64-bit variable b initializes to 4.0
  342. i: dq 8 ; a 64 bit integer
  343. five: dq 5.0 ; constant 5.0
  344. fmt: db "%s, a=%e, b=%e, c=%e",10,0 ; format string for printf
  345. section .bss ; uninitialized space
  346. c: resq 1 ; reserve a 64-bit word
  347. section .text ; instructions, code segment
  348. global main ; for gcc standard linking
  349. main: ; label
  350. push rbp ; set up stack
  351. lit5: ; c=5.0;
  352. fld qword [five] ; 5.0 constant
  353. fstp qword [c] ; store into c
  354. pabc "c=5.0" ; invoke the print macro
  355. addb: ; c=a+b;
  356. fld qword [a] ; load a (pushed on flt pt stack, st0)
  357. fadd qword [b] ; floating add b (to st0)
  358. fstp qword [c] ; store into c (pop flt pt stack)
  359. pabc "c=a+b" ; invoke the print macro
  360. subb: ; c=a-b;
  361. fld qword [a] ; load a (pushed on flt pt stack, st0)
  362. fsub qword [b] ; floating subtract b (to st0)
  363. fstp qword [c] ; store into c (pop flt pt stack)
  364. pabc "c=a-b" ; invoke the print macro
  365. mulb: ; c=a*b;
  366. fld qword [a] ; load a (pushed on flt pt stack, st0)
  367. fmul qword [b] ; floating multiply by b (to st0)
  368. fstp qword [c] ; store product into c (pop flt pt stack)
  369. pabc "c=a*b" ; invoke the print macro
  370. diva: ; c=c/a;
  371. fld qword [c] ; load c (pushed on flt pt stack, st0)
  372. fdiv qword [a] ; floating divide by a (to st0)
  373. fstp qword [c] ; store quotient into c (pop flt pt stack)
  374. pabc "c=c/a" ; invoke the print macro
  375. intflt: ; a=i;
  376. fild dword [i] ; load integer as floating point
  377. fst qword [a] ; store the floating point (no pop)
  378. fadd st0 ; b=a+i; 'a' as 'i' already on flt stack
  379. fst qword [b] ; store sum (no pop) 'b' still on stack
  380. fistp dword [i] ; i=b; store floating point as integer
  381. fild dword [i] ; c=i; load again from ram (redundant)
  382. fstp qword [c]
  383. pabc "a=i " ; invoke the print macro
  384. cmpflt: fld dword [b] ; into st0, then pushed to st1
  385. fld dword [a] ; in st0
  386. fcomip st0,st1 ; a compare b, pop a
  387. jg cmpfl2
  388. pabc "a<=b "
  389. jmp cmpfl3
  390. cmpfl2:
  391. pabc "a>b "
  392. cmpfl3:
  393. fld dword [c] ; should equal [b]
  394. fcomip st0,st1
  395. jne cmpfl4
  396. pabc "b==c "
  397. jmp cmpfl5
  398. cmpfl4:
  399. pabc "b!=c "
  400. cmpfl5:
  401. pop rbp ; pop stack
  402. mov rax,0 ; exit code, 0=normal
  403. ret ; main returns to operating system
  404. fib_64l.asm print 64-bit fib numbers
  405. The nasm source code is fib_64l.asm
  406. The result of the assembly is fib_64l.lst
  407. The equivalent "C" program is fib.c
  408. Running the program produces output fib_64l.out
  409. The nasm source code, like C, is fib_64m.asm
  410. The result of the assembly is fib_64m.lst
  411. Running the program produces output fib_64m.out
  412. Note: output may go negative when size of numbers
  413. exceed 63-bits without sign. Wrong results with overflow.
  414. This program demonstrates a loop, saving state between calls.
  415. First, the 64-bit C program:
  416. // fib.c same as computation as fib_64m.asm similar fib_64l.asm
  417. #include <stdio.h>
  418. int main(int argc, char *argv[])
  419. {
  420. long int c = 95; // loop counter
  421. long int a = 1; // current number, becomes next
  422. long int b = 2; // next number, becomes sum a+b
  423. long int d; // temp
  424. for(c=c; c!=0; c--)
  425. {
  426. printf("%21ld\n",a);
  427. d = a;
  428. a = b;
  429. b = d+b;
  430. }
  431. return 0;
  432. }
  433. Now, the first 64-bit assembly language implementation
  434. ; fib_64l.asm using 64 bit registers to implement fib.c
  435. global main
  436. extern printf
  437. section .data
  438. format: db '%15ld', 10, 0
  439. title: db 'fibinachi numbers', 10, 0
  440. section .text
  441. main:
  442. push rbp ; set up stack
  443. mov rdi, title ; arg 1 is a pointer
  444. mov rax, 0 ; no vector registers in use
  445. call printf
  446. mov rcx, 95 ; rcx will countdown from 52 to 0
  447. mov rax, 1 ; rax will hold the current number
  448. mov rbx, 2 ; rbx will hold the next number
  449. print:
  450. ; We need to call printf, but we are using rax, rbx, and rcx.
  451. ; printf may destroy rax and rcx so we will save these before
  452. ; the call and restore them afterwards.
  453. push rax ; 32-bit stack operands are not encodable
  454. push rcx ; in 64-bit mode, so we use the "r" names
  455. mov rdi, format ; arg 1 is a pointer
  456. mov rsi, rax ; arg 2 is the current number
  457. mov eax, 0 ; no vector registers in use
  458. call printf
  459. pop rcx
  460. pop rax
  461. mov rdx, rax ; save the current number
  462. mov rax, rbx ; next number is now current
  463. add rbx, rdx ; get the new next number
  464. dec rcx ; count down
  465. jnz print ; if not done counting, do some more
  466. pop rbp ; restore stack
  467. mov rax, 0 ; normal exit
  468. ret
  469. Now an implementation closer to C, storing variables
  470. ; fib_64m.asm using 64 bit memory more like C code
  471. ; // fib.c same as computation as fib_64m.asm
  472. ; #include
  473. ; int main(int argc, char *argv[])
  474. ; {
  475. ; long int c = 95; // loop counter
  476. ; long int a = 1; // current number, becomes next
  477. ; long int b = 2; // next number, becomes sum a+b
  478. ; long int d; // temp
  479. ; printf("fibinachi numbers\n");
  480. ; for(c=c; c!=0; c--)
  481. ; {
  482. ; printf("%21ld\n",a);
  483. ; d = a;
  484. ; a = b;
  485. ; b = d+b;
  486. ; }
  487. ; }
  488. global main
  489. extern printf
  490. section .bss
  491. d: resq 1 ; temp unused, kept in register rdx
  492. section .data
  493. c: dq 95 ; loop counter
  494. a: dq 1 ; current number, becomes next
  495. b: dq 2 ; next number, becomes sum a+b
  496. format: db '%15ld', 10, 0
  497. title: db 'fibinachi numbers', 10, 0
  498. section .text
  499. main:
  500. push rbp ; set up stack
  501. mov rdi, title ; arg 1 is a pointer
  502. mov rax, 0 ; no vector registers in use
  503. call printf
  504. print:
  505. ; We need to call printf, but we are using rax, rbx, and rcx.
  506. mov rdi, format ; arg 1 is a pointer
  507. mov rsi,[a] ; arg 2 is the current number
  508. mov rax, 0 ; no vector registers in use
  509. call printf
  510. mov rdx,[a] ; save the current number, in register
  511. mov rbx,[b] ;
  512. mov [a],rbx ; next number is now current, in ram
  513. add rbx, rdx ; get the new next number
  514. mov [b],rbx ; store in ram
  515. mov rcx,[c] ; get loop count
  516. dec rcx ; count down
  517. mov [c],rcx ; save in ram
  518. jnz print ; if not done counting, do some more
  519. pop rbp ; restore stack
  520. mov rax, 0 ; normal exit
  521. ret ; return to operating system
  522. loopint_64.asm simple loop
  523. The nasm source code is loopint_64.asm
  524. The result of the assembly is loopint_64.lst
  525. The equivalent "C" program is loopint_64.c
  526. Running the program produces output loopint_64.out
  527. This program demonstrates basic loop assembly language
  528. ; loopint_64.asm code loopint.c for nasm
  529. ; /* loopint_64.c a very simple loop that will be coded for nasm */
  530. ; #include <stdio.h>
  531. ; int main()
  532. ; {
  533. ; long int dd1[100]; // 100 could be 3 gigabytes
  534. ; long int i; // must be long for more than 2 gigabytes
  535. ; dd1[0]=5; /* be sure loop stays 1..98 */
  536. ; dd1[99]=9;
  537. ; for(i=1; i<99; i++) dd1[i]=7;
  538. ; printf("dd1[0]=%ld, dd1[1]=%ld, dd1[98]=%ld, dd1[99]=%ld\n",
  539. ; dd1[0], dd1[1], dd1[98],dd1[99]);
  540. ; return 0;
  541. ;}
  542. ; execution output is dd1[0]=5, dd1[1]=7, dd1[98]=7, dd1[99]=9
  543. section .bss
  544. dd1: resq 100 ; reserve 100 long int
  545. i: resq 1 ; actually unused, kept in register
  546. section .data ; Data section, initialized variables
  547. fmt: db "dd1[0]=%ld, dd1[1]=%ld, dd1[98]=%ld, dd1[99]=%ld",10,0
  548. extern printf ; the C function, to be called
  549. section .text
  550. global main
  551. main: push rbp ; set up stack
  552. mov qword [dd1],5 ; dd1[0]=5; memory to memory
  553. mov qword [dd1+99*8],9 ; dd1[99]=9; indexed 99 qword
  554. mov rdi, 1*8 ; i=1; index, will move by 8 bytes
  555. loop1: mov qword [dd1+rdi],7 ; dd1[i]=7;
  556. add rdi, 8 ; i++; 8 bytes
  557. cmp rdi, 8*99 ; i<99
  558. jne loop1 ; loop until incremented i=99
  559. mov rdi, fmt ; pass address of format
  560. mov rsi, qword [dd1] ; dd1[0] first list parameter
  561. mov rdx, qword [dd1+1*8] ; dd1[1] second list parameter
  562. mov rcx, qword [dd1+98*8] ; dd1[98] third list parameter
  563. mov r8, qword [dd1+99*8] ; dd1[99] fourth list parameter
  564. mov rax, 0 ; no xmm used
  565. call printf ; Call C function
  566. pop rbp ; restore stack
  567. mov rax,0 ; normal, no error, return value
  568. ret ; return 0;
  569. testreg_64.asm use rax, eax, ax, ah, al
  570. The nasm source code is testreg_64.asm
  571. The result of the assembly is testreg_64.lst
  572. This program demonstrates basic use of registers in assembly language
  573. ; testreg_64.asm test what register names can be used
  574. ;
  575. ; compile: nasm -f elf64 -l testreg_64.lst testasm_64.asm
  576. ; link: gcc -o testreg_64 testreg_64.o
  577. ; run: ./testreg # may get segfault or other error
  578. ;
  579. section .data ; preset constants, writable
  580. aa8: db 8 ; 8-bit
  581. aa16: dw 16 ; 16-bit
  582. aa32: dd 32 ; 32-bit
  583. aa64: dq 64 ; 64-bit
  584. section .bss
  585. bb16: resw 16
  586. section .rodata
  587. cc16: db 8
  588. section .text ; instructions, code segment
  589. global main ; for gcc standard linking
  590. main: ; label
  591. push rbp ; set up stack
  592. mov rax,[aa64] ; five registers in RAX
  593. mov eax,[aa32] ; four registers in EAX
  594. mov ax,[aa16]
  595. mov ah,[aa8]
  596. mov al,[aa8]
  597. mov RAX,[aa64] ; upper case register names
  598. mov EAX,[aa32]
  599. mov AX,[aa16]
  600. mov AH,[aa8]
  601. mov AL,[aa8]
  602. mov rbx,[aa64] ; five registers in RBX
  603. mov ebx,[aa32] ; four registers in EBX
  604. mov bx,[aa16]
  605. mov bh,[aa8]
  606. mov bl,[aa8]
  607. mov rcx,[aa64] ; five registers in RCX
  608. mov ecx,[aa32] ; four registers in ECX
  609. mov cx,[aa16]
  610. mov ch,[aa8]
  611. mov cl,[aa8]
  612. mov rdx,[aa64] ; five registers in RDX
  613. mov edx,[aa32] ; four registers in EDX
  614. mov dx,[aa16]
  615. mov dh,[aa8]
  616. mov dl,[aa8]
  617. mov rsi,[aa64] ; three registers in RSI
  618. mov esi,[aa32] ; two registers in ESI
  619. mov si,[aa16]
  620. mov rdi,[aa64] ; three registers in RDI
  621. mov edi,[aa32] ; two registers in EDI
  622. mov di,[aa16]
  623. mov rbp,[aa64] ; three registers in RBP
  624. mov ebp,[aa32] ; two registers in EBP
  625. mov bp,[aa16]
  626. mov r8,[aa64] ; just 64-bit r8 .. r15
  627. movq xmm0, qword [aa64] ; xmm registers special
  628. fld qword [aa64] ; floating point special
  629. ; POPF ; no "mov" on EFLAGS register
  630. ; PUSHF ; 32 bits on 386 and above
  631. ; mov rsp,[aa64] ; three registers in RSP
  632. ; mov esp,[aa32] ; two registers in ESP
  633. ; mov sp,[aa16] ; don't mess with stack
  634. pop rbp
  635. mov rax,0 ; exit code, 0=normal
  636. ret ; main returns to operating system
  637. ; end testreg_64.asm
  638. shift_64.asm shifting
  639. The nasm source code is shift_64.asm
  640. The result of the assembly is shift_64.lst
  641. Running the program produces output shift_64.out
  642. This program demonstrates basic shifting in assembly language
  643. ; shift_64.asm the nasm code is one sample, not unique
  644. ;
  645. ; compile: nasm -f elf64 -l shift_64.lst shift_64.asm
  646. ; link: gcc -o shift_64 shift_64.o
  647. ; run: ./shift_64 > shift_64.out
  648. ;
  649. ; the output from running shift.asm (zero filled) is:
  650. ; shl rax,4, old rax=ABCDEF0987654321, new rax=BCDEF09876543210,
  651. ; shl rax,8, old rax=ABCDEF0987654321, new rax=CDEF098765432100,
  652. ; shr rax,4, old rax=ABCDEF0987654321, new rax= ABCDEF098765432,
  653. ; sal rax,8, old rax=ABCDEF0987654321, new rax=CDEF098765432100,
  654. ; sar rax,4, old rax=ABCDEF0987654321, new rax=FABCDEF098765432,
  655. ; rol rax,4, old rax=ABCDEF0987654321, new rax=BCDEF0987654321A,
  656. ; ror rax,4, old rax=ABCDEF0987654321, new rax=1ABCDEF098765432,
  657. ; shld rdx,rax,8, old rdx:rax=0,ABCDEF0987654321,
  658. ; new rax=ABCDEF0987654321 rdx= AB,
  659. ; shl rax,8 , old rdx:rax=0,ABCDEF0987654321,
  660. ; new rax=CDEF098765432100 rdx= AB,
  661. ; shrd rdx,rax,8, old rdx:rax=0,ABCDEF0987654321,
  662. ; new rax=ABCDEF0987654321 rdx=2100000000000000,
  663. ; shr rax,8 , old rdx:rax=0,ABCDEF0987654321,
  664. ; new rax= ABCDEF09876543 rdx=2100000000000000,
  665. extern printf ; the C function to be called
  666. %macro prt 1 ; old and new rax
  667. section .data
  668. .str db %1,0 ; %1 is which shift string
  669. section .text
  670. mov rdi, fmt ; address of format string
  671. mov rsi, .str ; callers string
  672. mov rdx,rax ; new value
  673. mov rax, 0 ; no floating point
  674. call printf ; Call C function
  675. %endmacro
  676. %macro prt2 1 ; old and new rax,rdx
  677. section .data
  678. .str db %1,0 ; %1 is which shift
  679. section .text
  680. mov rdi, fmt2 ; address of format string
  681. mov rsi, .str ; callers string
  682. mov rcx, rdx ; new rdx befor next because used
  683. mov rdx, rax ; new rax
  684. mov rax, 0 ; no floating point
  685. call printf ; Call C function
  686. %endmacro
  687. section .bss
  688. raxsave: resq 1 ; save rax while calling a function
  689. rdxsave: resq 1 ; save rdx while calling a function
  690. section .data ; preset constants, writable
  691. b64: dq 0xABCDEF0987654321 ; data to shift
  692. fmt: db "%s, old rax=ABCDEF0987654321, new rax=%16lX, ",10,0 ; format string
  693. fmt2: db "%s, old rdx:rax=0,ABCDEF0987654321,",10," new rax=%16lX rdx=%16lX, ",10,0
  694. section .text ; instructions, code segment
  695. global main ; for gcc standard linking
  696. main: push rbp ; set up stack
  697. shl1: mov rax, [b64] ; data to shift
  698. shl rax, 4 ; shift rax 4 bits, one hex position left
  699. prt "shl rax,4 " ; invoke the print macro
  700. shl4: mov rax, [b64] ; data to shift
  701. shl rax,8 ; shift rax 8 bits. two hex positions left
  702. prt "shl rax,8 " ; invoke the print macro
  703. shr4: mov rax, [b64] ; data to shift
  704. shr rax,4 ; shift
  705. prt "shr rax,4 " ; invoke the print macro
  706. sal4: mov rax, [b64] ; data to shift
  707. sal rax,8 ; shift
  708. prt "sal rax,8 " ; invoke the print macro
  709. sar4: mov rax, [b64] ; data to shift
  710. sar rax,4 ; shift
  711. prt "sar rax,4 " ; invoke the print macro
  712. rol4: mov rax, [b64] ; data to shift
  713. rol rax,4 ; shift
  714. prt "rol rax,4 " ; invoke the print macro
  715. ror4: mov rax, [b64] ; data to shift
  716. ror rax,4 ; shift
  717. prt "ror rax,4 " ; invoke the print macro
  718. shld4: mov rax, [b64] ; data to shift
  719. mov rdx,0 ; register receiving bits
  720. shld rdx,rax,8 ; shift
  721. mov [raxsave],rax ; save, destroyed by function
  722. mov [rdxsave],rdx ; save, destroyed by function
  723. prt2 "shld rdx,rax,8"; invoke the print macro
  724. shla: mov rax,[raxsave] ; restore, destroyed by function
  725. mov rdx,[rdxsave] ; restore, destroyed by function
  726. shl rax,8 ; finish double shift, both registers
  727. prt2 "shl rax,8 "; invoke the print macro
  728. shrd4: mov rax, [b64] ; data to shift
  729. mov rdx,0 ; register receiving bits
  730. shrd rdx,rax,8 ; shift
  731. mov [raxsave],rax ; save, destroyed by function
  732. mov [rdxsave],rdx ; save, destroyed by function
  733. prt2 "shrd rdx,rax,8"; invoke the print macro
  734. shra: mov rax,[raxsave] ; restore, destroyed by function
  735. mov rdx,[rdxsave] ; restore, destroyed by function
  736. shr rax,8 ; finish double shift, both registers
  737. prt2 "shr rax,8 "; invoke the print macro
  738. pop rbp ; restore stack
  739. mov rax,0 ; exit code, 0=normal
  740. ret ; main returns to operating system
  741. ifint_64.asm if then else
  742. The nasm source code is ifint_64.asm
  743. The result of the assembly is ifint_64.lst
  744. The equivalent "C" program is ifint_64.c
  745. Running the program produces output ifint_64.out
  746. This program demonstrates basic if then else in assembly language
  747. ; ifint_64.asm code ifint_64.c for nasm
  748. ; /* ifint_64.c an 'if' statement that will be coded for nasm */
  749. ; #include <stdio.h>
  750. ; int main()
  751. ; {
  752. ; long int a=1;
  753. ; long int b=2;
  754. ; long int c=3;
  755. ; if(a<b)
  756. ; printf("true a < b \n");
  757. ; else
  758. ; printf("wrong on a < b \n");
  759. ; if(b>c)
  760. ; printf("wrong on b > c \n");
  761. ; else
  762. ; printf("false b > c \n");
  763. ; return 0;
  764. ;}
  765. ; result of executing both "C" and assembly is:
  766. ; true a < b
  767. ; false b > c
  768. global main ; define for linker
  769. extern printf ; tell linker we need this C function
  770. section .data ; Data section, initialized variables
  771. a: dq 1
  772. b: dq 2
  773. c: dq 3
  774. fmt1: db "true a < b ",10,0
  775. fmt2: db "wrong on a < b ",10,0
  776. fmt3: db "wrong on b > c ",10,0
  777. fmt4: db "false b > c ",10,0
  778. section .text
  779. main: push rbp ; set up stack
  780. mov rax,[a] ; a
  781. cmp rax,[b] ; compare a to b
  782. jge false1 ; choose jump to false part
  783. ; a < b sign is set
  784. mov rdi, fmt1 ; printf("true a < b \n");
  785. call printf
  786. jmp exit1 ; jump over false part
  787. false1: ; a < b is false
  788. mov rdi, fmt2 ; printf("wrong on a < b \n");
  789. call printf
  790. exit1: ; finished 'if' statement
  791. mov rax,[b] ; b
  792. cmp rax,[c] ; compare b to c
  793. jle false2 ; choose jump to false part
  794. ; b > c sign is not set
  795. mov rdi, fmt3 ; printf("wrong on b > c \n");
  796. call printf
  797. jmp exit2 ; jump over false part
  798. false2: ; b > c is false
  799. mov rdi, fmt4 ; printf("false b > c \n");
  800. call printf
  801. exit2: ; finished 'if' statement
  802. pop rbp ; restore stack
  803. mov rax,0 ; normal, no error, return value
  804. ret ; return 0;
  805. intlogic_64.asm bit logic, and, or
  806. The nasm source code is intlogic_64.asm
  807. The result of the assembly is intlogic_64.lst
  808. The equivalent "C" program is intlogic_64.c
  809. Running the program produces output intlogic_64.out
  810. This program demonstrates basic and, or, xor, not in assembly language
  811. ; intlogic_64.asm show some simple C code and corresponding nasm code
  812. ; the nasm code is one sample, not unique
  813. ;
  814. ; compile: nasm -f elf64 -l intlogic_64.lst intlogic_64.asm
  815. ; link: gcc -m64 -o intlogic_64 intlogic_64.o
  816. ; run: ./intlogic_64 > intlogic_64.out
  817. ;
  818. ; the output from running intlogic_64.asm and intlogic.c is
  819. ; c=5 , a=3, b=5, c=15
  820. ; c=a&b;, a=3, b=5, c=1
  821. ; c=a|b, a=3, b=5, c=7
  822. ; c=a^b, a=3, b=5, c=6
  823. ; c=~a , a=3, b=5, c=-4
  824. ;
  825. ;The file intlogic_64.c is:
  826. ; #include <stdio.h>
  827. ; int main()
  828. ; {
  829. ; long int a=3, b=5, c;
  830. ;
  831. ; c=15;
  832. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=5 ", a, b, c);
  833. ; c=a&b; /* and */
  834. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=a&b;", a, b, c);
  835. ; c=a|b; /* or */
  836. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=a|b", a, b, c);
  837. ; c=a^b; /* xor */
  838. ; printf("%s, a=%ld, b=%ld, c=%ld\n","c=a^b", a, b, c);
  839. ; c=~a; /* not */
  840. ; printf("%s, a=%ld, b=%ld, c=%d\n","c=~a", a, b, c);
  841. ; return 0;
  842. ; }
  843. extern printf ; the C function to be called
  844. %macro pabc 1 ; a "simple" print macro
  845. section .data
  846. .str db %1,0 ; %1 is first actual in macro call
  847. section .text
  848. mov rdi, fmt ; address of format string
  849. mov rsi, .str ; users string
  850. mov rdx, [a] ; long int a
  851. mov rcx, [b] ; long int b
  852. mov r8, [c] ; long int c
  853. mov rax, 0 ; no xmm used
  854. call printf ; Call C function
  855. %endmacro
  856. section .data ; preset constants, writable
  857. a: dq 3 ; 64-bit variable a initialized to 3
  858. b: dq 5 ; 64-bit variable b initializes to 4
  859. fmt: db "%s, a=%ld, b=%ld, c=%ld",10,0 ; format string for printf
  860. section .bss ; unitialized space
  861. c: resq 1 ; reserve a 64-bit word
  862. section .text ; instructions, code segment
  863. global main ; for gcc standard linking
  864. main: ; label
  865. push rbp ; set up stack
  866. lit5: ; c=5;
  867. mov rax,15 ; 5 is a literal constant
  868. mov [c],rax ; store into c
  869. pabc "c=5 " ; invoke the print macro
  870. andb: ; c=a&b;
  871. mov rax,[a] ; load a
  872. and rax,[b] ; and with b
  873. mov [c],rax ; store into c
  874. pabc "c=a&b;" ; invoke the print macro
  875. orw: ; c=a-b;
  876. mov rax,[a] ; load a
  877. or rax,[b] ; logical or with b
  878. mov [c],rax ; store into c
  879. pabc "c=a|b" ; invoke the print macro
  880. xorw: ; c=a^b;
  881. mov rax,[a] ; load a
  882. xor rax,[b] ; exclusive or with b
  883. mov [c],rax ; store result in c
  884. pabc "c=a^b" ; invoke the print macro
  885. notw: ; c=~a;
  886. mov rax,[a] ; load c
  887. not rax ; not, complement
  888. mov [c],rax ; store result into c
  889. pabc "c=~a " ; invoke the print macro
  890. pop rbp ; restore stack
  891. mov rax,0 ; exit code, 0=normal
  892. ret ; main returns to operating system
  893. horner_64.asm Horner polynomial evaluation
  894. The nasm source code is horner_64.asm
  895. The result of the assembly is horner_64.lst
  896. The equivalent "C" program is horner_64.c
  897. Running the program produces output horner_64.out
  898. This program demonstrates Horner method of evaluating polynomials,
  899. using both integer and floating point and indexing an array.
  900. ; horner_64.asm Horners method of evaluating polynomials
  901. ;
  902. ; given a polynomial Y = a_n X^n + a_n-1 X^n-1 + ... a_1 X + a_0
  903. ; a_n is the coefficient 'a' with subscript n. X^n is X to nth power
  904. ; compute y_1 = a_n * X + a_n-1
  905. ; compute y_2 = y_1 * X + a_n-2
  906. ; compute y_i = y_i-1 * X + a_n-i i=3..n
  907. ; thus y_n = Y = value of polynomial
  908. ;
  909. ; in assembly language:
  910. ; load some register with a_n, multiply by X
  911. ; add a_n-1, multiply by X, add a_n-2, multiply by X, ...
  912. ; finishing with the add a_0
  913. ;
  914. ; output from execution:
  915. ; a 6319
  916. ; aa 6319
  917. ; af 6.319000e+03
  918. extern printf
  919. section .data
  920. global main
  921. section .data
  922. fmta: db "a %ld",10,0
  923. fmtaa: db "aa %ld",10,0
  924. fmtflt: db "af %e",10,0
  925. section .text
  926. main: push rbp ; set up stack
  927. ; evaluate an integer polynomial, X=7, using a count
  928. section .data
  929. a: dq 2,5,-7,22,-9 ; coefficients of polynomial, a_n first
  930. X: dq 7 ; X = 7
  931. ; n=4, 8 bytes per coefficient
  932. section .text
  933. mov rax,[a] ; accumulate value here, get coefficient a_n
  934. mov rdi,1 ; subscript initialization
  935. mov rcx,4 ; loop iteration count initialization, n
  936. h3loop: imul rax,[X] ; * X (ignore edx)
  937. add rax,[a+8*rdi] ; + a_n-i
  938. inc rdi ; increment subscript
  939. loop h3loop ; decrement rcx, jump on non zero
  940. mov rsi, rax ; print rax
  941. mov rdi, fmta ; format
  942. mov rax, 0 ; no float
  943. call printf
  944. ; evaluate an integer polynomial, X=7, using a count as index
  945. ; optimal organization of data allows a three instruction loop
  946. section .data
  947. aa: dq -9,22,-7,5,2 ; coefficients of polynomial, a_0 first
  948. n: dq 4 ; n=4, 8 bytes per coefficient
  949. section .text
  950. mov rax,[aa+4*8] ; accumulate value here, get coefficient a_n
  951. mov rcx,[n] ; loop iteration count initialization, n
  952. h4loop: imul rax,[X] ; * X (ignore edx)
  953. add rax,[aa+8*rcx-8]; + aa_n-i
  954. loop h4loop ; decrement rcx, jump on non zero
  955. mov rsi, rax ; print rax
  956. mov rdi, fmtaa ; format
  957. mov rax, 0 ; no float
  958. call printf
  959. ; evaluate a double floating polynomial, X=7.0, using a count as index
  960. ; optimal organization of data allows a three instruction loop
  961. section .data
  962. af: dq -9.0,22.0,-7.0,5.0,2.0 ; coefficients of polynomial, a_0 first
  963. XF: dq 7.0
  964. Y: dq 0.0
  965. N: dd 4
  966. section .text
  967. mov rcx,[N] ; loop iteration count initialization, n
  968. fld qword [af+8*rcx]; accumulate value here, get coefficient a_n
  969. h5loop: fmul qword [XF] ; * XF
  970. fadd qword [af+8*rcx-8] ; + aa_n-i
  971. loop h5loop ; decrement rcx, jump on non zero
  972. fstp qword [Y] ; store Y in order to print Y
  973. movq xmm0, qword [Y] ; well, may just mov reg
  974. mov rdi, fmtflt ; format
  975. mov rax, 1 ; one float
  976. call printf
  977. pop rbp ; restore stack
  978. mov rax,0 ; normal return
  979. ret ; return
  980. call1_64.asm change callers array
  981. The nasm source code is call1_64.asm
  982. The main "C" program is test_call1_64.c
  983. Be safe, header file is call1_64.h
  984. The equivalent "C" program is call1_64.c
  985. Running the program produces output test_call1_64.out
  986. This program demonstrates passing an array to assembly language
  987. and the assembly language updating the array.
  988. ; call1_64.asm a basic structure for a subroutine to be called from "C"
  989. ;
  990. ; Parameter: long int *L
  991. ; Result: L[0]=L[0]+3 L[1]=L[1]+4
  992. global call1_64 ; linker must know name of subroutine
  993. extern printf ; the C function, to be called for demo
  994. SECTION .data ; Data section, initialized variables
  995. fmt1: db "rdi=%ld, L[0]=%ld", 10, 0 ; The printf format, "\n",'0'
  996. fmt2: db "rdi=%ld, L[1]=%ld", 10, 0 ; The printf format, "\n",'0'
  997. SECTION .bss
  998. a: resq 1 ; temp for printing
  999. SECTION .text ; Code section.
  1000. call1_64: ; name must appear as a nasm label
  1001. push rbp ; save rbp
  1002. mov rbp, rsp ; rbp is callers stack
  1003. push rdx ; save registers
  1004. push rdi
  1005. push rsi
  1006. mov rax,rdi ; first, only, in parameter
  1007. mov [a],rdi ; save for later use
  1008. mov rdi,fmt1 ; format for printf debug, demo
  1009. mov rsi,rax ; first parameter for printf
  1010. mov rdx,[rax] ; second parameter for printf
  1011. mov rax,0 ; no xmm registers
  1012. call printf ; Call C function
  1013. mov rax,[a] ; first, only, in parameter, demo
  1014. mov rdi,fmt2 ; format for printf
  1015. mov rsi,rax ; first parameter for printf
  1016. mov rdx,[rax+8] ; second parameter for printf
  1017. mov rax,0 ; no xmm registers
  1018. call printf ; Call C function
  1019. mov rax,[a] ; add 3 to L[0]
  1020. mov rdx,[rax] ; get L[0]
  1021. add rdx,3 ; add
  1022. mov [rax],rdx ; store sum for caller
  1023. mov rdx,[rax+8] ; get L[1]
  1024. add rdx,4 ; add
  1025. mov [rax+8],rdx ; store sum for caller
  1026. pop rsi ; restore registers
  1027. pop rdi ; in reverse order
  1028. pop rdx
  1029. mov rsp,rbp ; restore callers stack frame
  1030. pop rbp
  1031. ret ; return