Archetypical Example: Euclid's Method of Computing Greatest Common Divisors (assembler, return address on separate stack) 超典型的ソースコードの見本~最大公約数を計算する、ユークリッドの互除法 (アセンブラ、帰還位置を別のスタックに)

形式
Asm
投稿日時
2015-03-31 15:21
公開期間
無期限
  1. .file "gcddummy.c"
  2. /* Not optimizing, to keep parallel with real compile. */
  3. /* Shims for n parameter single-stack functions (4 byte parameters) */
  4. /* The target address is in %eax */
  5. .text
  6. .globl shim5p
  7. .type shim5p, @function
  8. shim5p:
  9. pushl 16(%ebp)
  10. pushl 12(%ebp)
  11. pushl 8(%ebp)
  12. pushl 4(%ebp)
  13. pushl (%ebp)
  14. call *%eax
  15. addl $20, %esp
  16. ret
  17. .size shim5p, .-shim5p
  18. .text
  19. .globl shim4p
  20. .type shim4p, @function
  21. shim4p:
  22. pushl 12(%ebp)
  23. pushl 8(%ebp)
  24. pushl 4(%ebp)
  25. pushl (%ebp)
  26. call *%eax
  27. addl $16, %esp
  28. ret
  29. .size shim4p, .-shim4p
  30. .text
  31. .globl shim3p
  32. .type shim3p, @function
  33. shim3p:
  34. pushl 8(%ebp)
  35. pushl 4(%ebp)
  36. pushl (%ebp)
  37. call *%eax
  38. addl $12, %esp
  39. ret
  40. .size shim3p, .-shim3p
  41. .text
  42. .globl shim2p
  43. .type shim2p, @function
  44. shim2p:
  45. pushl 4(%ebp)
  46. pushl (%ebp)
  47. call *%eax
  48. addl $8, %esp
  49. ret
  50. .size shim2p, .-shim2p
  51. .text
  52. .globl shim1p
  53. .type shim1p, @function
  54. shim1p:
  55. pushl (%ebp)
  56. call *%eax
  57. addl $4, %esp
  58. ret
  59. .size shim1p, .-shim1p
  60. .text
  61. .globl gcd
  62. .type gcd, @function
  63. gcd:
  64. pushl %ebp /* Frame for unwinding */
  65. subl $4, %ebp /* Locals */
  66. jmp .L2
  67. .L3:
  68. movl 4(%ebp), %eax /* numA */
  69. cmpl 8(%ebp), %eax /* numB */
  70. jge .L4
  71. movl 4(%ebp), %eax /* numA */
  72. movl %eax, (%ebp) /* temp */
  73. movl 8(%ebp), %eax /* numB */
  74. movl %eax, 4(%ebp) /* numA */
  75. movl (%ebp), %eax /* temp */
  76. movl %eax, 8(%ebp) /* numB */
  77. .L4:
  78. movl 8(%ebp), %eax /* numB */
  79. subl %eax, 4(%ebp) /* numA */
  80. .L2:
  81. movl 4(%ebp), %eax /* numA */
  82. cmpl 8(%ebp), %eax /* numB */
  83. jne .L3
  84. movl 4(%ebp), %eax /* numA */
  85. popl %ebp /* Restore previous frame */
  86. ret
  87. .size gcd, .-gcd
  88. .section .rodata
  89. .LC0:
  90. .string "usage: %s <numA> <numB>\n"
  91. .align 4
  92. .LC1:
  93. .string "\tto calculate the greatest common divisor\n\tof two unsigned numbers."
  94. .LC2:
  95. .string "greatest common divisor: %ld\n"
  96. .LC3:
  97. .string "%ld/%ld => %ld/%ld\n"
  98. .align 4
  99. .LC4:
  100. .string "%s is not an unsigned number I can recognize.\n"
  101. .align 4
  102. .LC5:
  103. .string "Failed to allocate parameter stack in %s, errno: %d.\n"
  104. .align 4
  105. .type .LSSH0, @object
  106. .size .LSSH0, 5
  107. .LSSH0:
  108. .string "main"
  109. .text
  110. .globl main
  111. .type main, @function
  112. main:
  113. leal 4(%esp), %ecx
  114. andl $-16, %esp
  115. pushl -4(%ecx)
  116. pushl %ebp
  117. movl %esp, %ebp
  118. pushl %esi
  119. pushl %ebx
  120. pushl %ecx
  121. subl $60, %esp
  122. call __i686.get_pc_thunk.bx
  123. addl $_GLOBAL_OFFSET_TABLE_, %ebx /* strings */
  124. movl %ecx, %esi /* main arguments' base address */
  125. movl 4(%esi), %eax
  126. movl %eax, -48(%ebp)
  127. movl __guard_local@GOTOFF(%ebx), %eax
  128. movl %eax, -16(%ebp)
  129. xorl %eax, %eax
  130. /* Allocate the stack (in gcddummy.c)
  131. movl $4, 4(%esp)
  132. movl $1024, (%esp)
  133. call calloc@PLT
  134. // Do it way up high, instead.
  135. */
  136. call __errno@PLT /* Clear errno. */
  137. movl $0, (%eax)
  138. /* Make sure there's room on the stack for seven parameters. */
  139. subl $28, %esp
  140. /* address suggestion, 64Mb below system supplied stack. */
  141. leal -65536*1024(%esp), %eax
  142. movl %eax, (%esp)
  143. movl $65536, 4(%esp) /* size, 64Kb */
  144. movl $3, 8(%esp) /* PROT_READ | PROT_WRITE allowed */
  145. /* MAP_PRIVATE | MAP_ANONYMOUS | MAP_TRYFIXED mode flags */
  146. movl $4098, 12(%esp)
  147. movl $-1, 16(%esp) /* file descriptor to map to (none). */
  148. movl $0, 20(%esp) /* offset of mapping */
  149. movl $0, 24(%esp) /* parameter list terminator, I think. */
  150. call mmap@PLT
  151. addl $28, %esp /* Remove the parameters. */
  152. movl %eax, -36(%ebp) /* pstack (gcddummy.c) */
  153. call __errno@PLT
  154. movl (%eax), %eax
  155. cmpl $0, %eax
  156. je myentry
  157. movl %eax, 8(%esp) /* errno. (3 paramaters is within static allocation.) */
  158. movl -48(%ebp), %eax /* argv */
  159. movl (%eax), %eax /* argv[ 0 ] */
  160. movl %eax, 4(%esp)
  161. leal .LC5@GOTOFF(%ebx), %eax
  162. movl %eax, (%esp)
  163. call printf@PLT
  164. movl $1, %eax /* EXIT_FAILURE */
  165. jmp myexit
  166. myentry:
  167. movl -36(%ebp), %eax /* pstack */
  168. movl %eax, 4(%esp) /* Remember the lower bounds/alloc address. */
  169. /* Shift bp to the parameter stack pointer safely. */
  170. leal 1020*4(%eax), %edx /* Bumper zone. */
  171. movl $0, (%edx)
  172. movl $0, 4(%edx)
  173. movl $0, 8(%edx)
  174. movl $0, 12(%edx)
  175. /* Program "global" parameters to move to the parameter stack, or pre-allocate. */
  176. subl $7*4, %edx /* Allocate all the parameters. */
  177. /* %esi 6 -- Pointer to main's first argument, argc. */
  178. movl %esi, 6*4(%edx) /* Copy */
  179. /* -48(%ebp) 5 -- argv */
  180. movl -48(%ebp), %eax /* Copy */
  181. movl %eax, 5*4(%edx)
  182. /* -52(%ebp) 4 -- exit code, just allocate */
  183. /* -28(%ebp) 3 -- parseP, just allocate */
  184. /* -20(%ebp) 2 -- n1, just allocate */
  185. /* -24(%ebp) 1 -- n2, just allocate */
  186. /* -32(%ebp) 0 -- divisor, just allocate */
  187. movl %ebp, (%esp) /* Keep %ebp for restoring later. ("old frame pointer") */
  188. /* Set up %ebp as the parameter stack pointer: */
  189. movl %edx, %ebp
  190. /* From here to .L11, do NOT reference %esp for parameters or variables! */
  191. movl 6*4(%ebp), %eax /* argc (first arg of main) */
  192. cmpl $3, %eax
  193. je .L9
  194. subl $2*4, %ebp /* allocate, lazily */
  195. movl 7*4(%ebp), %eax /* argv */
  196. movl (%eax), %eax /* argv[ 0 ] */
  197. movl %eax, 1*4(%ebp)
  198. leal .LC0@GOTOFF(%ebx), %eax
  199. movl %eax, (%ebp)
  200. movl $printf@PLT, %eax
  201. call shim2p
  202. leal .LC1@GOTOFF(%ebx), %eax
  203. movl %eax, (%ebp)
  204. movl $puts@PLT, %eax
  205. call shim1p
  206. addl $2*4, %ebp /* deallocate, lazily */
  207. movl $1, 4*4(%ebp) /* EXIT_FAILURE */
  208. jmp .L11
  209. .L9:
  210. subl $3*4, %ebp /* allocate */
  211. movl 8*4(%ebp), %eax /* argv */
  212. addl $4, %eax
  213. movl (%eax), %edx /* arg[ 1 ] */
  214. movl $0, 2*4(%ebp)
  215. leal 6*4(%ebp), %eax /* &parseP */
  216. movl %eax, 1*4(%ebp)
  217. movl %edx, (%ebp) /* arg[ 1 ] */
  218. movl $strtoul@PLT, %eax
  219. call shim3p
  220. movl %eax, 5*4(%ebp) /* n1 */
  221. addl $3*4, %ebp /* deallocate */
  222. movl 5*4(%ebp), %eax /* argv */
  223. addl $4, %eax
  224. movl (%eax), %edx /* argv[ 1 ] */
  225. movl 3*4(%ebp), %eax /* parseP */
  226. cmpl %eax, %edx
  227. jae .L12
  228. subl $3*4, %ebp /* allocate */
  229. movl 8*4(%ebp), %eax /* argv */
  230. addl $8, %eax
  231. movl (%eax), %edx /* argv[ 1 ] */
  232. movl $0, 2*4(%ebp)
  233. leal 6*4(%ebp), %eax /* &parseP */
  234. movl %eax, 1*4(%ebp)
  235. movl %edx, (%ebp) /* argv[ 1 ] */
  236. movl $strtoul@PLT, %eax
  237. call shim3p
  238. movl %eax, 4*4(%ebp) /* n2 */
  239. addl $3*4, %ebp /* deallocate */
  240. movl 5*4(%ebp), %eax /* argv */
  241. addl $8, %eax
  242. movl (%eax), %edx /* argv[ 1 ] */
  243. movl 3*4(%ebp), %eax /* parseP */
  244. cmpl %eax, %edx
  245. jae .L14
  246. /* Make the call to gcd() */
  247. subl $2*4, %ebp /* allocate parameters */
  248. movl 3*4(%ebp), %eax /* n2 */
  249. movl %eax, 1*4(%ebp)
  250. movl 4*4(%ebp), %eax /* n1 */
  251. movl %eax, (%ebp)
  252. call gcd /* No shim! (Yay!) */
  253. addl $2*4, %ebp
  254. /* Recover the return value. */
  255. movl %eax, (%ebp) /* divisor */
  256. subl 5*4, %ebp /* allocate, lazily */
  257. movl 5*4(%ebp), %eax /* divisor */
  258. movl %eax, 1*4(%ebp)
  259. leal .LC2@GOTOFF(%ebx), %eax
  260. movl %eax, (%ebp)
  261. movl $printf@PLT, %eax
  262. call shim2p
  263. movl 6*4(%ebp), %edx /* n2 */
  264. movl %edx, %eax
  265. sarl $31, %edx
  266. idivl 5*4(%ebp) /* divisor */
  267. movl %eax, %ecx
  268. movl 7*4(%ebp), %edx /* n1 */
  269. movl %edx, %eax
  270. sarl $31, %edx
  271. idivl 5*4(%ebp) /* divisor */
  272. movl %ecx, 4*4(%ebp) /* n2 / divisor */
  273. movl %eax, 3*4(%ebp) /* n1 / divisor */
  274. movl 6*4(%ebp), %eax /* n2 */
  275. movl %eax, 2*4(%ebp)
  276. movl 7*4(%ebp), %eax /* n1 */
  277. movl %eax, 1*4(%ebp)
  278. leal .LC3@GOTOFF(%ebx), %eax
  279. movl %eax, (%ebp)
  280. movl $printf@PLT, %eax
  281. call shim5p
  282. addl 5*4, %ebp /* deallocate, lazily */
  283. movl $0, 4*4(%ebp) /* EXIT_SUCCESS */
  284. jmp .L11
  285. .L14:
  286. subl 2*4, %ebp /* allocate */
  287. movl 7*4(%ebp), %eax /* argv */
  288. addl $8, %eax
  289. movl (%eax), %eax /* argv[ 2 ] */
  290. movl %eax, 1*4(%ebp)
  291. leal .LC4@GOTOFF(%ebx), %eax
  292. movl %eax, (%ebp)
  293. movl $printf@PLT, %eax
  294. call shim2p
  295. addl 2*4, %ebp /* deallocate */
  296. jmp .L16
  297. .L12:
  298. subl 2*4, %ebp /* allocate */
  299. movl 7*4(%ebp), %eax /* argv */
  300. addl $4, %eax
  301. movl (%eax), %eax /* argv[ 1 ] */
  302. movl %eax, 1*4(%ebp)
  303. leal .LC4@GOTOFF(%ebx), %eax
  304. movl %eax, (%ebp)
  305. movl $printf@PLT, %eax
  306. call shim2p
  307. addl 2*4, %ebp /* deallocate */
  308. .L16:
  309. movl $1, 4*4(%ebp) /* EXIT_FAILURE */
  310. .L11:
  311. movl 4*4(%ebp), %eax /* But the exit code is on the parameter stack. */
  312. movl (%esp), %ebp /* restore ebp, drop the parameter stack. */
  313. movl %eax, -52(%ebp) /* exit code in interleaved stack */
  314. /* Forgot to free in gcddummy.c.
  315. movl 4(%esp), %eax
  316. movl %eax, (%esp)
  317. call free@PLT
  318. */
  319. /* But we mmap()ed it instead. */
  320. movl $65536, 4(%esp) /* requested length */
  321. movl -36(%ebp), %eax /* pstack */
  322. movl %eax, (%esp)
  323. call munmap@PLT
  324. movl -52(%ebp), %eax /* exit code to exit with */
  325. myexit:
  326. movl -16(%ebp), %edx
  327. xorl __guard_local@GOTOFF(%ebx), %edx
  328. je .L18
  329. /* Trap a bad return address. */
  330. leal .LSSH0@GOTOFF(%ebx), %eax /* walk on the exit code */
  331. movl %eax, (%esp)
  332. call __stack_smash_handler@PLT /* catch smash attempt */
  333. /* Valid exit: */
  334. .L18:
  335. addl $60, %esp
  336. popl %ecx
  337. popl %ebx
  338. popl %esi
  339. popl %ebp
  340. leal -4(%ecx), %esp
  341. ret
  342. .size main, .-main
  343. .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
  344. .globl __i686.get_pc_thunk.bx
  345. .hidden __i686.get_pc_thunk.bx
  346. .type __i686.get_pc_thunk.bx, @function
  347. __i686.get_pc_thunk.bx:
  348. movl (%esp), %ebx
  349. ret
ダウンロード 印刷用表示

このコピペの URL

JavaScript での埋め込み

iframe での埋め込み

元のテキスト