このサガは多くの写本の中に残されているが、特に大きく3つの版に分けられ、それぞれ「H版」「R版」「U版」と呼ばれている。H版とR版は犢皮紙の写本に残されていたものである。H版とは、Haukr Erlendsson（1334年没）の「ハウクスボーク」(A.M. 544, 4to) のものであり、およそ1325年頃のものである。R版とは、15世紀頃の写本『MS 2845, 4to』のことであり、この写本はコペンハーゲンのデンマーク王立図書館に保管されている。U版と呼ばれている版は、ウプサラの大学図書館カロリーナ・レディヴィヴァ (Carolina Rediviva) 所蔵の「R:715」と、コペンハーゲンの大学図書館所蔵「AM 203 fol」に、それぞれ部分的に残されていたものである。この版は17世紀ごろのものであり、Villingaholt に住んでいた Síra Jón Erlendsson（1672年没）によって書かれたものである。しかしながら、これらの資料の間にはいくつかの相違点がある。たとえばR版は最も原版に近いとされているが、しかし最初の一章と最後の部分が欠けている。その一方で、ヒャールマルの死の歌を含んでいる版でもある。またR版はH版よりもU版に近い。H版はゲストゥムブリンディについての記述で締めくくられているが、R版はちょうど12章の終わりの前で途切れている。しかしながら、H版には2つの17世紀の写し、「AM 281 4to」(h1) と「AM 597b 4to」(h2) があり、それらにはH版にみられるゲストゥムブリンディの謎掛けの場面が残されていた。
このサガのある部分は、しばしば古エッダに含まれることがある。たとえばヘルヴォルがアンガンチュールの霊と語る場面は『ヘルヴォルの歌』（Hervararkviða、または『アンガンチュールの目覚め』）として、またアンガンチュールとフロズルの争いは『フロズルの歌』（Hlǫðskviða、または『フン戦争の歌』）と呼ばれている。
ヘルヴォルとヘイズレク王のサガ (ON. Hervarar saga ok Heiðreks) とは、13世紀に成立した伝説のサガ（物語）である。他の何本かの古いサガから要素を取り出し、まとめたものではないかと考えられている。このサガは、その文学的品質に加え、いくつかの理由によって価値の有るサガとみなされている。このサガには4世紀に起こったゴート族とフン族との間の戦争に関する伝承が含まれており、またサガの後半はスウェーデン中世史の資料として用いられている。また、J・R・R・トールキンが中つ国の設定を構想する上で、このサガにインスピレーションを受けたといわれている。
山上に師事して甲冑の製作、復元修理を行っていた甲冑師・明珍宗恭の証言によると、癖の強い性格の持ち主で、研究者仲間やコレクターとの関係はあまりよくなかったようである。旅先や取材先でも奇行やいたずらに及ぶことがたびたびあったという。
山上が帝国学士院より受賞した研究『日本甲冑の新研究』は、上下巻を合わせて2500ページに迫る膨大なもので、その中で紹介されている日本全国の甲冑資料も、非常に豊富である。現代の甲冑研究にも強い影響を与え続けている大著である。
以下のC言語コードは、配列を検索して 5 より大きい値を探す処理を行うものである。まず、イテレータを使ったコードを示す。 int i; for (i = 0; i < length; i++) {     if (array[i] > 5) {          break;     } }  if (i < length) {     printf("Item %d\n", i); } else {     printf("Not found\n"); }次に、コールバックを使ったコードを示す。 /* ライブラリコード */ int traverseWith(int array[], size_t length,                   int (*callback)(int index, int item, void *param),                   void *param) {     int exitCode = 0;     for (int i = 0; i < length; i++) {         exitCode = callback(i, array[i], param);         if (exitCode) {              break;         }     }     return exitCode; }   /* アプリケーションコード */ int search (int index, int item, void *param) {     if (item > 5) {         *(int *)param = index;         return 1;     } else {         return 0;     } }  /* ライブラリを呼び出す本体 */ int index; int found; found = traverseWith(array, length, search, &index); if (found) {     printf("Item %d\n", index); } else {     printf("Not found\n"); }コールバック関数 search の if 文の条件を変更すれば、「5より大きい」以外の要素を検索するのにも使える。traverseWith には、コールバックが自身の目的のために受け取る追加の引数 param がある点に注意されたい。通常のコールバックでは、そのような引数をスコープ外のアプリケーションデータへのポインタに利用する。これは静的スコープ方式の言語（C や C++）でのみ必要とされる（ただし、C++ を含めたオブジェクト指向言語には別の解決策がある）。動的スコープの言語（関数型言語など）ではクロージャによって自動的にアプリケーションデータへのアクセスが可能となる。例として同じプログラムを LISP で書いた場合を示す。 ; ライブラリコード (defun traverseWith (array callback)   (let ((exitCode nil)         (i 0))     (while (and (not exitCode) (< i (length array)))       (setq exitCode (callback i (aref array i)))       (setq i (+ i 1)))     exitCode))  ; アプリケーションコード (let (index found)   (setq found (traverseWith array (lambda (idx item)                                     (if (<= item 5) nil                                       (setq index idx)                                       t)))))この場合、コールバック関数は使う時点で定義されており、"index" を名前で参照している。これらの例では同期に関する考慮は省略されているが、traverseWith 関数を同期できるように対処するのは容易である。さらに重要なことは、同期するかしないかをその関数の修正だけで対処できる点である。