diofanto33

main.s.final

Jun 11th, 2026
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.43 KB | None | 0 0
  1. .section .maze, "aw"
  2. .align 3
  3. .global laberinto
  4. .section .data
  5. estado: .dword 0x4e45204f4745554a, 0x21214f5352554320
  6. _stack_ptr: .dword _stack_end
  7.  
  8. // ------------- Modificar para agregar datos constantes --------------
  9.  
  10. // --------------------------------------------------------------------
  11.  
  12. .section .text
  13. .global _start
  14.  
  15. // Constantes
  16. .equ ESPACIO, 0x20
  17. .equ SALIDA, 0x23
  18. .equ PERSONA, 0x58
  19.  
  20. // Direcciones relativas al personaje
  21. .equ DIR_UP, 0
  22. .equ DIR_RIGHT, 1
  23. .equ DIR_DOWN, 2
  24. .equ DIR_LEFT, 3
  25.  
  26. _start:
  27. ldr x1, =_stack_ptr
  28. ldr x1, [x1]
  29. mov sp, x1
  30. mov x0, xzr
  31. mov x4, xzr
  32. ldr x0, =laberinto
  33.  
  34.  
  35. /* w11 es flag para indicar si se puede avanzar o no.
  36. * x19 es flag para indicar la direccion actual:
  37. * 0 = arriba, 1 = derecha, 2 = abajo, 3 = izquierda.
  38. * x1 es el contador de pasos.
  39. * x3 es la fila, x4 es la columna. (x3, x4) es una coodernada
  40. *
  41. */
  42.  
  43. main:
  44. // ------------- El código principal debe ir aqui abajo ---------------
  45.  
  46. // Iniciamos el contador de pasos en 0
  47. mov x1, xzr
  48.  
  49. // Buscamos la posicion inicial de X en el laberinto
  50. // x9 tendra la dirección de memoria de X
  51. bl seeking_x
  52.  
  53. // Orientación inicial mirando hacia abajo DIR_DOWN = 2
  54. // x19 mira para abajo
  55. mov x19, #DIR_DOWN
  56.  
  57. // Hand-on-wall rule
  58. // https://en.wikipedia.org/wiki/Maze-solving_algorithm
  59. resolve_loop:
  60. // Intentamos ir a la izquierda relativa (relativa a x19)
  61. bl turn_left
  62. // Chequeamos si podemos avanzar a la izquierda relativa a x19
  63. bl peek_forward
  64. // si w11=0, entonces es transitable,
  65. // si w11=1 entonces es pared, seguimos intentando
  66. cbz w11, do_move
  67.  
  68. // Como no pudimos ir a la izquierda,
  69. // deshacemos el giro
  70. bl turn_right
  71.  
  72. // Intentamos ir al frente (relativo a x19)
  73. bl peek_forward
  74. // si w11=0, entonces es transitable,
  75. // si w11=1 entonces es pared, seguimos intentando
  76. cbz w11, do_move
  77.  
  78. // No pudimos ir al frente, entonces
  79. // Intentamos ir a la derecha (relativa a x19)
  80. bl turn_right
  81. bl peek_forward
  82. // si w11=0, entonces es transitable,
  83. // si w11=1 entonces es pared, seguimos intentando
  84. cbz w11, do_move
  85.  
  86. // No pudimos ir a la derecha, entonces
  87. // Intentamos ir para atrás (relativo a x19)
  88. // Como ya estabamos mirando a la derecha de x19,
  89. // girar a la derecha otra vez nos deja mirando para atrás de x19,
  90. bl turn_right
  91. // intentar avanzar para atrás
  92. bl peek_forward
  93. cbz w11, do_move
  94.  
  95. // callejon sin salida, no deberia suceder en un laberinto valido
  96. b resolve_loop
  97.  
  98. do_move:
  99. // Luz verde para avanzar,
  100. // x19 es la dirección a la que estamos mirando,
  101.  
  102. // Calculamos coordenadas destino (x12, x13)
  103. mov x12, x3
  104. mov x13, x4
  105.  
  106. // Si estamos mirando para arriba, la fila destino es fila-1
  107. cmp x19, #DIR_UP
  108. b.eq do_move_up
  109. // Si estamos mirando para la derecha, la columna destino es col+1
  110. cmp x19, #DIR_RIGHT
  111. b.eq do_move_right
  112. // Si estamos mirando para abajo, la fila destino es fila+1
  113. cmp x19, #DIR_DOWN
  114. b.eq do_move_down
  115. // Si estamos mirando para la izquierda, la columna destino es col-1
  116. sub x13, x13, #1
  117. b do_move_map
  118. do_move_up:
  119. // fila destino es fila-1
  120. sub x12, x12, #1
  121. b do_move_map
  122. do_move_right:
  123. add x13, x13, #1
  124. b do_move_map
  125. do_move_down:
  126. add x12, x12, #1
  127.  
  128. do_move_map:
  129. // calculamos direccion destino
  130. // x14 = base + fila*16 + col
  131. mov x14, x0
  132. mov x15, #16
  133. madd x14, x15, x12, x14
  134. add x14, x14, x13
  135.  
  136. // en este punto x14 es la direccion destino
  137.  
  138. // leemos el byte destino
  139. ldrb w5, [x14]
  140.  
  141. // verificamos si es la salida
  142. cmp w5, #SALIDA
  143. b.eq reached_exit
  144.  
  145. // Como no era salida, entonces es un espacio transitable, avanzamos,
  146. // escribimos espacio en la posición vieja (x9 = dirección actual de X)
  147. mov w8, #ESPACIO
  148. strb w8, [x9]
  149.  
  150. // escribimos X en la posición nueva (x14 = dirección destino)
  151. mov w8, #PERSONA
  152. strb w8, [x14]
  153.  
  154. // seteamos coordenadas actuales a las coordenadas destino
  155. // es decir, donde ahora se encuentra el personaje X
  156. mov x3, x12
  157. mov x4, x13
  158. mov x9, x14
  159.  
  160. // incrementar contador de pasos
  161. add x1, x1, #1
  162.  
  163. // seguimos intentando
  164. b resolve_loop
  165.  
  166.  
  167. /*
  168. * La funcion reached_exit se llama cuando el personaje
  169. * llega a la salida del laberinto. Escribe "Juego finalizado"
  170. * en el estado, y luego entra en un loop infinito.
  171. */
  172.  
  173. reached_exit:
  174. ldr x20, =estado
  175. mov x21, #0x754A
  176. movk x21, #0x6765, lsl #16
  177. movk x21, #0x206F, lsl #32
  178. movk x21, #0x6966, lsl #48
  179. str x21, [x20]
  180. mov x22, #0x616E
  181. movk x22, #0x6C69, lsl #16
  182. movk x22, #0x617A, lsl #32
  183. movk x22, #0x6F64, lsl #48
  184. str x22, [x20, #8]
  185. add x1, x1, #1
  186.  
  187. // --------------------------------------------------------------------
  188.  
  189. infloop: b infloop
  190.  
  191.  
  192. /*
  193. * peek_forward chequea si la celda al frente es transitable
  194. *
  195. * Como el personaje puede estar mirando en cualquier dirección (x19),
  196. * calcula cuál es la celda al frente y lee su contenido en memoria.
  197. *
  198. * La dirección de memoria del destino se calcula con la formula del paper:
  199. * dir = base + fila*16 + columna
  200. * Luego lee el byte y lo compara con ESPACIO (0x20) y SALIDA (0x23).
  201. *
  202. * @param x0 = dirección base del laberinto
  203. * @param x3 = fila actual del personaje
  204. * @param x4 = columna actual del personaje
  205. * @param x19 = orientación actual (DIR_UP=0, DIR_RIGHT=1, DIR_DOWN=2, DIR_LEFT=3)
  206. *
  207. * @return w11 = 0 si la celda al frente es transitable (ESPACIO o SALIDA)
  208. * w11 = 1 si es pared u otro caracter no transitable
  209. *
  210. * Temporales: x12 para fila destino,
  211. * x13 para columna destino,
  212. * x14 para direccion destino,
  213. * x15 para multiplicar fila por 16
  214. *
  215. * No modifica: x0, x3, x4, x9, x19
  216. */
  217. peek_forward:
  218. mov x12, x3
  219. mov x13, x4
  220.  
  221. // si estamos mirando arriba, la fila destino es fila-1
  222. cmp x19, #DIR_UP
  223. b.eq peek_forward_up
  224. // si estamos mirando a la derecha, la columna destino es col+1
  225. cmp x19, #DIR_RIGHT
  226. b.eq peek_forward_right
  227. // si estamos mirando abajo, la fila destino es fila+1
  228. cmp x19, #DIR_DOWN
  229. b.eq peek_forward_down
  230. // si estamos mirando a la izquierda, la columna destino es col-1
  231. sub x13, x13, #1
  232. b peek_forward_map
  233. peek_forward_up:
  234. sub x12, x12, #1
  235. b peek_forward_map
  236. peek_forward_right:
  237. add x13, x13, #1
  238. b peek_forward_map
  239. peek_forward_down:
  240. add x12, x12, #1
  241.  
  242. peek_forward_map:
  243. // Calculamos la dirección destino
  244. // dirección = base + fila*16 + col
  245. mov x14, x0
  246. mov x15, #16
  247. madd x14, x15, x12, x14
  248. add x14, x14, x13
  249.  
  250. // Leemos el byte destino
  251. ldrb w5, [x14]
  252.  
  253. // Comparamos con espacio y salida
  254. cmp w5, #ESPACIO
  255. b.eq peek_forward_go
  256. cmp w5, #SALIDA
  257. b.eq peek_forward_go
  258. // no es ni espacio ni salida, entonces no es transitable
  259. // seteamos la flag w11 a 1 para indicar que no se puede avanzar
  260. mov w11, #1
  261. b peek_forward_end
  262. peek_forward_go:
  263. // es transitable,
  264. // seteamos la flag w11 a 0 para indicar que se puede avanzar
  265. mov w11, #0
  266. peek_forward_end:
  267. // retornamos
  268. br x30
  269.  
  270.  
  271.  
  272. // GIROS relativos a la direccion actual (x19)
  273.  
  274. /* turn_left */
  275. turn_left:
  276. sub x19, x19, #1
  277. and x19, x19, #3
  278. br x30
  279.  
  280. /* turn_right */
  281. turn_right:
  282. add x19, x19, #1
  283. and x19, x19, #3
  284. br x30
  285.  
  286. /* turn_back */
  287. turn_back:
  288. add x19, x19, #2
  289. and x19, x19, #3
  290. br x30
  291.  
  292.  
  293. /*
  294. * map: x9 = base + x3*16 + x4
  295. * @param x0=base, x3=fila, x4=col
  296. * @return x9=dirección
  297. */
  298. map:
  299. mov x15, #16
  300. mov x9, x0
  301. madd x9, x15, x3, x9
  302. add x9, x9, x4
  303. br x30
  304.  
  305.  
  306. /*
  307. * seeking_x busca la X en el laberinto,
  308. * recorre el laberinto byte a byte hasta encontrar la X,
  309. * y calcula su fila y columna.
  310. *
  311. * @param x0 = dirección base
  312. * @return x9 = dirección de X, x3 = fila, x4 = columna
  313. */
  314. seeking_x:
  315. mov x3, xzr
  316. mov x4, xzr
  317. mov x9, x0
  318. seeking_x_loop:
  319. ldrb w11, [x9]
  320. cmp w11, #PERSONA
  321. b.eq x_found
  322. add x9, x9, #1
  323. b seeking_x_loop
  324. x_found:
  325. sub x10, x9, x0
  326. lsr x3, x10, #4
  327. and x4, x10, #0xF
  328. br x30
  329.  
  330.  
  331. // Movimientos absolutos
  332.  
  333. /* move_left */
  334. move_left:
  335. mov x26, x30
  336. bl map
  337. mov x7, x9
  338. sub x9, x9, #1
  339. ldrb w5, [x9]
  340. cmp w5, #SALIDA
  341. b.eq move_left_exit
  342. cmp w5, #ESPACIO
  343. b.ne move_left_fail
  344. mov w8, #ESPACIO
  345. strb w8, [x7]
  346. mov w8, #PERSONA
  347. strb w8, [x9]
  348. sub x4, x4, #1
  349. add x1, x1, #1
  350. mov w11, #0
  351. b move_left_end
  352. move_left_fail:
  353. mov w11, #1
  354. b move_left_end
  355. move_left_exit:
  356. add x1, x1, #1
  357. b reached_exit
  358.  
  359. move_left_end:
  360. br x26
  361.  
  362.  
  363. /* move_right */
  364. move_right:
  365. mov x26, x30
  366. bl map
  367. mov x7, x9
  368. add x9, x9, #1
  369. ldrb w5, [x9]
  370. cmp w5, #SALIDA
  371. b.eq move_right_exit
  372. cmp w5, #ESPACIO
  373. b.ne move_right_fail
  374. mov w8, #ESPACIO
  375. strb w8, [x7]
  376. mov w8, #PERSONA
  377. strb w8, [x9]
  378. add x4, x4, #1
  379. add x1, x1, #1
  380. mov w11, #0
  381. b move_right_end
  382.  
  383. move_right_fail:
  384. mov w11, #1
  385. b move_right_end
  386. move_right_exit:
  387. add x1, x1, #1
  388. b reached_exit
  389. move_right_end:
  390. br x26
  391.  
  392.  
  393. /* move_down */
  394. move_down:
  395. mov x26, x30
  396. bl map
  397. mov x7, x9
  398. add x3, x3, #1
  399. bl map
  400. ldrb w5, [x9]
  401. cmp w5, #SALIDA
  402. b.eq move_down_exit
  403. cmp w5, #ESPACIO
  404. b.ne move_down_fail
  405. mov w8, #ESPACIO
  406. strb w8, [x7]
  407. mov w8, #PERSONA
  408. strb w8, [x9]
  409. add x1, x1, #1
  410. mov w11, #0
  411. b move_down_end
  412.  
  413. move_down_fail:
  414. sub x3, x3, #1
  415. mov w11, #1
  416. b move_down_end
  417. move_down_exit:
  418. add x1, x1, #1
  419. b reached_exit
  420. move_down_end:
  421. br x26
  422.  
  423. move_up:
  424. mov x26, x30
  425. bl map
  426. mov x7, x9
  427. sub x3, x3, #1
  428. bl map
  429. ldrb w5, [x9]
  430. cmp w5, #SALIDA
  431. b.eq move_up_exit
  432. cmp w5, #ESPACIO
  433. b.ne move_up_fail
  434. mov w8, #ESPACIO
  435. strb w8, [x7]
  436. mov w8, #PERSONA
  437. strb w8, [x9]
  438. add x1, x1, #1
  439. mov w11, #0
  440. b move_up_end
  441.  
  442. move_up_fail:
  443. add x3, x3, #1
  444. mov w11, #1
  445. b move_up_end
  446. move_up_exit:
  447. add x1, x1, #1
  448. b reached_exit
  449.  
  450. move_up_end:
  451. br x26
  452.  
Advertisement
Add Comment
Please, Sign In to add comment