NCurses Countdown to New Years Day

For those less graphically inclined, I also wrote a different version of the app experimenting with the ncurses TUI library (text based library), used for interactive text console apps. Not as exciting, but I wanted to learn another aspect of programming, by starting at the basics.

#include <ncurses.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

int main() {
  initscr();
  curs_set(0);

  int max_x, max_y;
  getmaxyx(stdscr, max_y, max_x);

  struct tm nyd = { 0 }; /* inits struct members to 0 */
  nyd.tm_year = 2025-1900;
  nyd.tm_mday = 1; 

  time_t nyd_time = mktime(&nyd);
  
  while (true) {
  
    time_t diff = difftime(nyd_time, time(NULL));

    char buf[80];

    snprintf(buf, 80, "%3d %17s", (int) diff/86400, "days");
    mvprintw(max_y/2-2, (max_x-strlen(buf))/2, "%s", buf);

    snprintf(buf, 80, "%3d %17s", (int) (diff % 86400) / 3600, "hours");
    mvprintw(max_y/2-1, (max_x-strlen(buf))/2, "%s", buf);

    snprintf(buf, 80, "%3d %17s", (int) (diff % 3600) / 60, "minutes" );
    mvprintw(max_y/2, (max_x-strlen(buf))/2, "%s", buf);

    snprintf(buf, 80, "%3d %17s", (int) diff % 60, "seconds");
    mvprintw(max_y/2+1, (max_x-strlen(buf))/2, "%s", buf);

    attron(A_BOLD);
    
    strncpy(buf, "New Years Day 2025!", 80);
    mvprintw(max_y/2+3, (max_x-strlen(buf))/2, "%s", buf);

    attroff(A_BOLD);

    refresh();

    sleep(1);
  }

  endwin();

  return 0;
}

As I’ve been sick with the COVID, I also have been carefully studying the x86 Assembler code generated by the compiler. It’s quite fascinating.

0000000000401206 <main>:
#include <ncurses.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

int main() {
  401206:	55                   	push   %rbp
  401207:	48 89 e5             	mov    %rsp,%rbp
  40120a:	53                   	push   %rbx
  40120b:	48 81 ec a8 00 00 00 	sub    $0xa8,%rsp
  initscr();
  401212:	e8 79 fe ff ff       	call   401090 <initscr@plt>
  curs_set(0);
  401217:	bf 00 00 00 00       	mov    $0x0,%edi
  40121c:	e8 cf fe ff ff       	call   4010f0 <curs_set@plt>

  int max_x, max_y;
  getmaxyx(stdscr, max_y, max_x);
  401221:	48 8b 05 58 2e 00 00 	mov    0x2e58(%rip),%rax        # 404080 <stdscr@@Base>
  401228:	48 89 c7             	mov    %rax,%rdi
  40122b:	e8 20 fe ff ff       	call   401050 <getmaxy@plt>
  401230:	89 45 ec             	mov    %eax,-0x14(%rbp)
  401233:	48 8b 05 46 2e 00 00 	mov    0x2e46(%rip),%rax        # 404080 <stdscr@@Base>
  40123a:	48 89 c7             	mov    %rax,%rdi
  40123d:	e8 9e fe ff ff       	call   4010e0 <getmaxx@plt>
  401242:	89 45 e8             	mov    %eax,-0x18(%rbp)

  struct tm nyd = { 0 }; /* inits struct members to 0 */
  401245:	66 0f ef c0          	pxor   %xmm0,%xmm0
  401249:	0f 29 45 a0          	movaps %xmm0,-0x60(%rbp)
  40124d:	0f 29 45 b0          	movaps %xmm0,-0x50(%rbp)
  401251:	0f 29 45 c0          	movaps %xmm0,-0x40(%rbp)
  401255:	66 0f d6 45 d0       	movq   %xmm0,-0x30(%rbp)
  nyd.tm_year = 2025-1900;
  40125a:	c7 45 b4 7d 00 00 00 	movl   $0x7d,-0x4c(%rbp)
  nyd.tm_mday = 1; 
  401261:	c7 45 ac 01 00 00 00 	movl   $0x1,-0x54(%rbp)

  time_t nyd_time = mktime(&nyd);
  401268:	48 8d 45 a0          	lea    -0x60(%rbp),%rax
  40126c:	48 89 c7             	mov    %rax,%rdi
  40126f:	e8 5c fe ff ff       	call   4010d0 <mktime@plt>
  401274:	48 89 45 e0          	mov    %rax,-0x20(%rbp)
  
  while (true) {
  
    time_t diff = difftime(nyd_time, time(NULL));
  401278:	bf 00 00 00 00       	mov    $0x0,%edi
  40127d:	e8 3e fe ff ff       	call   4010c0 <time@plt>
  401282:	48 89 c2             	mov    %rax,%rdx
  401285:	48 8b 45 e0          	mov    -0x20(%rbp),%rax
  401289:	48 89 d6             	mov    %rdx,%rsi
  40128c:	48 89 c7             	mov    %rax,%rdi
  40128f:	e8 ec fd ff ff       	call   401080 <difftime@plt>
  401294:	f2 48 0f 2c c0       	cvttsd2si %xmm0,%rax
  401299:	48 89 45 d8          	mov    %rax,-0x28(%rbp)

    char buf[80];

    snprintf(buf, 80, "%3d %17s", (int) diff/86400, "days");
  40129d:	48 8b 45 d8          	mov    -0x28(%rbp),%rax
  4012a1:	48 63 d0             	movslq %eax,%rdx
  4012a4:	48 69 d2 07 45 2e c2 	imul   $0xffffffffc22e4507,%rdx,%rdx
  4012ab:	48 c1 ea 20          	shr    $0x20,%rdx
  4012af:	01 c2                	add    %eax,%edx
  4012b1:	c1 fa 10             	sar    $0x10,%edx
  4012b4:	c1 f8 1f             	sar    $0x1f,%eax
  4012b7:	29 c2                	sub    %eax,%edx
  4012b9:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  4012c0:	41 b8 10 20 40 00    	mov    $0x402010,%r8d
  4012c6:	89 d1                	mov    %edx,%ecx
  4012c8:	ba 15 20 40 00       	mov    $0x402015,%edx
  4012cd:	be 50 00 00 00       	mov    $0x50,%esi
  4012d2:	48 89 c7             	mov    %rax,%rdi
  4012d5:	b8 00 00 00 00       	mov    $0x0,%eax
  4012da:	e8 c1 fd ff ff       	call   4010a0 <snprintf@plt>
    mvprintw(max_y/2-2, (max_x-strlen(buf))/2, "%s", buf);
  4012df:	8b 45 e8             	mov    -0x18(%rbp),%eax
  4012e2:	48 63 d8             	movslq %eax,%rbx
  4012e5:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  4012ec:	48 89 c7             	mov    %rax,%rdi
  4012ef:	e8 6c fd ff ff       	call   401060 <strlen@plt>
  4012f4:	48 29 c3             	sub    %rax,%rbx
  4012f7:	48 89 da             	mov    %rbx,%rdx
  4012fa:	48 89 d0             	mov    %rdx,%rax
  4012fd:	48 d1 e8             	shr    $1,%rax
  401300:	89 c6                	mov    %eax,%esi
  401302:	8b 45 ec             	mov    -0x14(%rbp),%eax
  401305:	89 c2                	mov    %eax,%edx
  401307:	c1 ea 1f             	shr    $0x1f,%edx
  40130a:	01 d0                	add    %edx,%eax
  40130c:	d1 f8                	sar    $1,%eax
  40130e:	8d 78 fe             	lea    -0x2(%rax),%edi
  401311:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  401318:	48 89 c1             	mov    %rax,%rcx
  40131b:	ba 1e 20 40 00       	mov    $0x40201e,%edx
  401320:	b8 00 00 00 00       	mov    $0x0,%eax
  401325:	e8 e6 fd ff ff       	call   401110 <mvprintw@plt>

    snprintf(buf, 80, "%3d %17s", (int) (diff % 86400) / 3600, "hours");
  40132a:	48 8b 4d d8          	mov    -0x28(%rbp),%rcx
  40132e:	48 ba 57 29 51 ce a0 	movabs $0x1845c8a0ce512957,%rdx
  401335:	c8 45 18 
  401338:	48 89 c8             	mov    %rcx,%rax
  40133b:	48 f7 ea             	imul   %rdx
  40133e:	48 89 d0             	mov    %rdx,%rax
  401341:	48 c1 f8 0d          	sar    $0xd,%rax
  401345:	48 89 ca             	mov    %rcx,%rdx
  401348:	48 c1 fa 3f          	sar    $0x3f,%rdx
  40134c:	48 29 d0             	sub    %rdx,%rax
  40134f:	48 69 d0 80 51 01 00 	imul   $0x15180,%rax,%rdx
  401356:	48 89 c8             	mov    %rcx,%rax
  401359:	48 29 d0             	sub    %rdx,%rax
  40135c:	48 63 d0             	movslq %eax,%rdx
  40135f:	48 69 d2 c5 b3 a2 91 	imul   $0xffffffff91a2b3c5,%rdx,%rdx
  401366:	48 c1 ea 20          	shr    $0x20,%rdx
  40136a:	01 c2                	add    %eax,%edx
  40136c:	c1 fa 0b             	sar    $0xb,%edx
  40136f:	c1 f8 1f             	sar    $0x1f,%eax
  401372:	29 c2                	sub    %eax,%edx
  401374:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  40137b:	41 b8 21 20 40 00    	mov    $0x402021,%r8d
  401381:	89 d1                	mov    %edx,%ecx
  401383:	ba 15 20 40 00       	mov    $0x402015,%edx
  401388:	be 50 00 00 00       	mov    $0x50,%esi
  40138d:	48 89 c7             	mov    %rax,%rdi
  401390:	b8 00 00 00 00       	mov    $0x0,%eax
  401395:	e8 06 fd ff ff       	call   4010a0 <snprintf@plt>
    mvprintw(max_y/2-1, (max_x-strlen(buf))/2, "%s", buf);
  40139a:	8b 45 e8             	mov    -0x18(%rbp),%eax
  40139d:	48 63 d8             	movslq %eax,%rbx
  4013a0:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  4013a7:	48 89 c7             	mov    %rax,%rdi
  4013aa:	e8 b1 fc ff ff       	call   401060 <strlen@plt>
  4013af:	48 29 c3             	sub    %rax,%rbx
  4013b2:	48 89 da             	mov    %rbx,%rdx
  4013b5:	48 89 d0             	mov    %rdx,%rax
  4013b8:	48 d1 e8             	shr    $1,%rax
  4013bb:	89 c6                	mov    %eax,%esi
  4013bd:	8b 45 ec             	mov    -0x14(%rbp),%eax
  4013c0:	89 c2                	mov    %eax,%edx
  4013c2:	c1 ea 1f             	shr    $0x1f,%edx
  4013c5:	01 d0                	add    %edx,%eax
  4013c7:	d1 f8                	sar    $1,%eax
  4013c9:	8d 78 ff             	lea    -0x1(%rax),%edi
  4013cc:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  4013d3:	48 89 c1             	mov    %rax,%rcx
  4013d6:	ba 1e 20 40 00       	mov    $0x40201e,%edx
  4013db:	b8 00 00 00 00       	mov    $0x0,%eax
  4013e0:	e8 2b fd ff ff       	call   401110 <mvprintw@plt>

    snprintf(buf, 80, "%3d %17s", (int) (diff % 3600) / 60, "minutes" );
  4013e5:	48 8b 4d d8          	mov    -0x28(%rbp),%rcx
  4013e9:	48 ba 05 7c f3 6a e2 	movabs $0x48d159e26af37c05,%rdx
  4013f0:	59 d1 48 
  4013f3:	48 89 c8             	mov    %rcx,%rax
  4013f6:	48 f7 ea             	imul   %rdx
  4013f9:	48 89 d0             	mov    %rdx,%rax
  4013fc:	48 c1 f8 0a          	sar    $0xa,%rax
  401400:	48 89 ca             	mov    %rcx,%rdx
  401403:	48 c1 fa 3f          	sar    $0x3f,%rdx
  401407:	48 29 d0             	sub    %rdx,%rax
  40140a:	48 69 d0 10 0e 00 00 	imul   $0xe10,%rax,%rdx
  401411:	48 89 c8             	mov    %rcx,%rax
  401414:	48 29 d0             	sub    %rdx,%rax
  401417:	48 63 d0             	movslq %eax,%rdx
  40141a:	48 69 d2 89 88 88 88 	imul   $0xffffffff88888889,%rdx,%rdx
  401421:	48 c1 ea 20          	shr    $0x20,%rdx
  401425:	01 c2                	add    %eax,%edx
  401427:	c1 fa 05             	sar    $0x5,%edx
  40142a:	c1 f8 1f             	sar    $0x1f,%eax
  40142d:	29 c2                	sub    %eax,%edx
  40142f:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  401436:	41 b8 27 20 40 00    	mov    $0x402027,%r8d
  40143c:	89 d1                	mov    %edx,%ecx
  40143e:	ba 15 20 40 00       	mov    $0x402015,%edx
  401443:	be 50 00 00 00       	mov    $0x50,%esi
  401448:	48 89 c7             	mov    %rax,%rdi
  40144b:	b8 00 00 00 00       	mov    $0x0,%eax
  401450:	e8 4b fc ff ff       	call   4010a0 <snprintf@plt>
    mvprintw(max_y/2, (max_x-strlen(buf))/2, "%s", buf);
  401455:	8b 45 e8             	mov    -0x18(%rbp),%eax
  401458:	48 63 d8             	movslq %eax,%rbx
  40145b:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  401462:	48 89 c7             	mov    %rax,%rdi
  401465:	e8 f6 fb ff ff       	call   401060 <strlen@plt>
  40146a:	48 29 c3             	sub    %rax,%rbx
  40146d:	48 89 da             	mov    %rbx,%rdx
  401470:	48 89 d0             	mov    %rdx,%rax
  401473:	48 d1 e8             	shr    $1,%rax
  401476:	89 c6                	mov    %eax,%esi
  401478:	8b 45 ec             	mov    -0x14(%rbp),%eax
  40147b:	89 c2                	mov    %eax,%edx
  40147d:	c1 ea 1f             	shr    $0x1f,%edx
  401480:	01 d0                	add    %edx,%eax
  401482:	d1 f8                	sar    $1,%eax
  401484:	89 c7                	mov    %eax,%edi
  401486:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  40148d:	48 89 c1             	mov    %rax,%rcx
  401490:	ba 1e 20 40 00       	mov    $0x40201e,%edx
  401495:	b8 00 00 00 00       	mov    $0x0,%eax
  40149a:	e8 71 fc ff ff       	call   401110 <mvprintw@plt>

    snprintf(buf, 80, "%3d %17s", (int) diff % 60, "seconds");
  40149f:	48 8b 45 d8          	mov    -0x28(%rbp),%rax
  4014a3:	89 c2                	mov    %eax,%edx
  4014a5:	48 63 c2             	movslq %edx,%rax
  4014a8:	48 69 c0 89 88 88 88 	imul   $0xffffffff88888889,%rax,%rax
  4014af:	48 c1 e8 20          	shr    $0x20,%rax
  4014b3:	01 d0                	add    %edx,%eax
  4014b5:	c1 f8 05             	sar    $0x5,%eax
  4014b8:	89 d1                	mov    %edx,%ecx
  4014ba:	c1 f9 1f             	sar    $0x1f,%ecx
  4014bd:	29 c8                	sub    %ecx,%eax
  4014bf:	6b c8 3c             	imul   $0x3c,%eax,%ecx
  4014c2:	89 d0                	mov    %edx,%eax
  4014c4:	29 c8                	sub    %ecx,%eax
  4014c6:	48 8d bd 50 ff ff ff 	lea    -0xb0(%rbp),%rdi
  4014cd:	41 b8 2f 20 40 00    	mov    $0x40202f,%r8d
  4014d3:	89 c1                	mov    %eax,%ecx
  4014d5:	ba 15 20 40 00       	mov    $0x402015,%edx
  4014da:	be 50 00 00 00       	mov    $0x50,%esi
  4014df:	b8 00 00 00 00       	mov    $0x0,%eax
  4014e4:	e8 b7 fb ff ff       	call   4010a0 <snprintf@plt>
    mvprintw(max_y/2+1, (max_x-strlen(buf))/2, "%s", buf);
  4014e9:	8b 45 e8             	mov    -0x18(%rbp),%eax
  4014ec:	48 63 d8             	movslq %eax,%rbx
  4014ef:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  4014f6:	48 89 c7             	mov    %rax,%rdi
  4014f9:	e8 62 fb ff ff       	call   401060 <strlen@plt>
  4014fe:	48 29 c3             	sub    %rax,%rbx
  401501:	48 89 da             	mov    %rbx,%rdx
  401504:	48 89 d0             	mov    %rdx,%rax
  401507:	48 d1 e8             	shr    $1,%rax
  40150a:	89 c6                	mov    %eax,%esi
  40150c:	8b 45 ec             	mov    -0x14(%rbp),%eax
  40150f:	89 c2                	mov    %eax,%edx
  401511:	c1 ea 1f             	shr    $0x1f,%edx
  401514:	01 d0                	add    %edx,%eax
  401516:	d1 f8                	sar    $1,%eax
  401518:	8d 78 01             	lea    0x1(%rax),%edi
  40151b:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  401522:	48 89 c1             	mov    %rax,%rcx
  401525:	ba 1e 20 40 00       	mov    $0x40201e,%edx
  40152a:	b8 00 00 00 00       	mov    $0x0,%eax
  40152f:	e8 dc fb ff ff       	call   401110 <mvprintw@plt>

    attron(A_BOLD);
  401534:	48 8b 05 45 2b 00 00 	mov    0x2b45(%rip),%rax        # 404080 <stdscr@@Base>
  40153b:	ba 00 00 00 00       	mov    $0x0,%edx
  401540:	be 00 00 20 00       	mov    $0x200000,%esi
  401545:	48 89 c7             	mov    %rax,%rdi
  401548:	e8 f3 fa ff ff       	call   401040 <wattr_on@plt>
    
    strncpy(buf, "New Years Day 2025!", 80);
  40154d:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  401554:	ba 50 00 00 00       	mov    $0x50,%edx
  401559:	be 37 20 40 00       	mov    $0x402037,%esi
  40155e:	48 89 c7             	mov    %rax,%rdi
  401561:	e8 ca fa ff ff       	call   401030 <strncpy@plt>
    mvprintw(max_y/2+3, (max_x-strlen(buf))/2, "%s", buf);
  401566:	8b 45 e8             	mov    -0x18(%rbp),%eax
  401569:	48 63 d8             	movslq %eax,%rbx
  40156c:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  401573:	48 89 c7             	mov    %rax,%rdi
  401576:	e8 e5 fa ff ff       	call   401060 <strlen@plt>
  40157b:	48 29 c3             	sub    %rax,%rbx
  40157e:	48 89 da             	mov    %rbx,%rdx
  401581:	48 89 d0             	mov    %rdx,%rax
  401584:	48 d1 e8             	shr    $1,%rax
  401587:	89 c6                	mov    %eax,%esi
  401589:	8b 45 ec             	mov    -0x14(%rbp),%eax
  40158c:	89 c2                	mov    %eax,%edx
  40158e:	c1 ea 1f             	shr    $0x1f,%edx
  401591:	01 d0                	add    %edx,%eax
  401593:	d1 f8                	sar    $1,%eax
  401595:	8d 78 03             	lea    0x3(%rax),%edi
  401598:	48 8d 85 50 ff ff ff 	lea    -0xb0(%rbp),%rax
  40159f:	48 89 c1             	mov    %rax,%rcx
  4015a2:	ba 1e 20 40 00       	mov    $0x40201e,%edx
  4015a7:	b8 00 00 00 00       	mov    $0x0,%eax
  4015ac:	e8 5f fb ff ff       	call   401110 <mvprintw@plt>

    attroff(A_BOLD);
  4015b1:	48 8b 05 c8 2a 00 00 	mov    0x2ac8(%rip),%rax        # 404080 <stdscr@@Base>
  4015b8:	ba 00 00 00 00       	mov    $0x0,%edx
  4015bd:	be 00 00 20 00       	mov    $0x200000,%esi
  4015c2:	48 89 c7             	mov    %rax,%rdi
  4015c5:	e8 e6 fa ff ff       	call   4010b0 <wattr_off@plt>

    refresh();
  4015ca:	48 8b 05 af 2a 00 00 	mov    0x2aaf(%rip),%rax        # 404080 <stdscr@@Base>
  4015d1:	48 89 c7             	mov    %rax,%rdi
  4015d4:	e8 97 fa ff ff       	call   401070 <wrefresh@plt>

    sleep(1);
  4015d9:	bf 01 00 00 00       	mov    $0x1,%edi
  4015de:	e8 1d fb ff ff       	call   401100 <sleep@plt>
  while (true) {
  4015e3:	90                   	nop
  4015e4:	e9 8f fc ff ff       	jmp    401278 <main+0x72>

Map: Alma Pond
Map: Dobbins Memorial State Forest
Map: Donahue Woods State Forest
Map: Little John Wildlife Management Area
Map: Otter Lake
Map: South Hill State Forest (Oneida 23)
Map: Summer Hill State Forest
Map: West Parishville State Forest
SVGZ Graphic: albany-snow-depth
SVGZ Graphic: college-rate
SVGZ Graphic: december-holidays
SVGZ Graphic: ht2025
SVGZ Graphic: Increase in Price for a Gallon of Regular Gas Since May 13, 2025 [Expires May 27 2026]
SVGZ Graphic: lt2025
SVGZ Graphic: May-sunset [Expires May 27 2026]
SVGZ Graphic: Places Named Bethlehem
SVGZ Graphic: Towns with Most Similiar Land Cover to the Town of Bethlehem
Terrain Map: Happy World Milk Day!
Photo: Troy
Photo: Farm Country
Photo: Camping on Forest Road 13
Photo: Long Trail
Photo: Along the way
Photo: Ducks
Photo: Home For The Weekend
Photo: Off the ski run
Photo: Autumn
Photo: Quiet Waters

Leave a Reply

Your email address will not be published. Required fields are marked *